mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
Texture::set_quality_level()
This commit is contained in:
parent
11aaf2ffce
commit
acb0faae46
@ -447,6 +447,23 @@ appear before they are referenced.
|
||||
the polygon itself. See the description for draw_order under
|
||||
polygon attributes.
|
||||
|
||||
<Scalar> quality-level { quality }
|
||||
|
||||
Sets a hint to the renderer about the desired performance /
|
||||
quality tradeoff for this particular texture. This is most useful
|
||||
for the tinydisplay software renderer; for normal,
|
||||
hardware-accelerated renderers, this may have little or no effect.
|
||||
|
||||
This may be one of:
|
||||
|
||||
DEFAULT
|
||||
FASTEST
|
||||
NORMAL
|
||||
BEST
|
||||
|
||||
"Default" means to use whatever quality level is specified by the
|
||||
global texture-quality-level config variable.
|
||||
|
||||
<Transform> { transform-definition }
|
||||
|
||||
This specifies a 2-d or 3-d transformation that is applied to the
|
||||
|
@ -441,6 +441,26 @@ get_tex_gen() const {
|
||||
return _tex_gen;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTexture::set_quality_level
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggTexture::
|
||||
set_quality_level(QualityLevel quality_level) {
|
||||
_quality_level = quality_level;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTexture::get_quality_level
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggTexture::QualityLevel EggTexture::
|
||||
get_quality_level() const {
|
||||
return _quality_level;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTexture::set_stage_name
|
||||
// Access: Published
|
||||
|
@ -48,6 +48,7 @@ EggTexture(const string &tref_name, const string &filename)
|
||||
_env_type = ET_unspecified;
|
||||
_saved_result = false;
|
||||
_tex_gen = TG_unspecified;
|
||||
_quality_level = QL_unspecified;
|
||||
_priority = 0;
|
||||
_color.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_border_color.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
@ -93,6 +94,7 @@ operator = (const EggTexture ©) {
|
||||
_env_type = copy._env_type;
|
||||
_saved_result = copy._saved_result;
|
||||
_tex_gen = copy._tex_gen;
|
||||
_quality_level = copy._quality_level;
|
||||
_stage_name = copy._stage_name;
|
||||
_priority = copy._priority;
|
||||
_color = copy._color;
|
||||
@ -237,6 +239,11 @@ write(ostream &out, int indent_level) const {
|
||||
<< "<Scalar> tex-gen { " << get_tex_gen() << " }\n";
|
||||
}
|
||||
|
||||
if (get_quality_level() != QL_unspecified) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> quality-level { " << get_quality_level() << " }\n";
|
||||
}
|
||||
|
||||
if (has_stage_name()) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Scalar> stage-name { " << get_stage_name() << " }\n";
|
||||
@ -1050,6 +1057,35 @@ string_tex_gen(const string &string) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTexture::string_quality_level
|
||||
// Access: Published, Static
|
||||
// Description: Returns the TexGen value associated with the given
|
||||
// string representation, or ET_unspecified if the string
|
||||
// does not match any known TexGen value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggTexture::QualityLevel EggTexture::
|
||||
string_quality_level(const string &string) {
|
||||
if (cmp_nocase_uh(string, "unspecified") == 0) {
|
||||
return QL_unspecified;
|
||||
|
||||
} else if (cmp_nocase_uh(string, "default") == 0) {
|
||||
return QL_default;
|
||||
|
||||
} else if (cmp_nocase_uh(string, "fastest") == 0) {
|
||||
return QL_fastest;
|
||||
|
||||
} else if (cmp_nocase_uh(string, "normal") == 0) {
|
||||
return QL_normal;
|
||||
|
||||
} else if (cmp_nocase_uh(string, "best") == 0) {
|
||||
return QL_best;
|
||||
|
||||
} else {
|
||||
return QL_unspecified;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTexture::as_transform
|
||||
// Access: Public, Virtual
|
||||
@ -1469,3 +1505,21 @@ operator << (ostream &out, EggTexture::TexGen tex_gen) {
|
||||
|
||||
return out << "**invalid TexGen(" << (int)tex_gen << ")**";
|
||||
}
|
||||
|
||||
ostream &
|
||||
operator << (ostream &out, EggTexture::QualityLevel quality_level) {
|
||||
switch (quality_level) {
|
||||
case EggTexture::QL_unspecified:
|
||||
return out << "unspecified";
|
||||
case EggTexture::QL_default:
|
||||
return out << "default";
|
||||
case EggTexture::QL_fastest:
|
||||
return out << "fastest";
|
||||
case EggTexture::QL_normal:
|
||||
return out << "normal";
|
||||
case EggTexture::QL_best:
|
||||
return out << "best";
|
||||
}
|
||||
|
||||
return out << "**invalid QualityLevel(" << (int)quality_level << ")**";
|
||||
}
|
||||
|
@ -162,6 +162,13 @@ PUBLISHED:
|
||||
|
||||
TG_point_sprite,
|
||||
};
|
||||
enum QualityLevel {
|
||||
QL_unspecified,
|
||||
QL_default,
|
||||
QL_fastest,
|
||||
QL_normal,
|
||||
QL_best,
|
||||
};
|
||||
|
||||
INLINE void set_texture_type(TextureType texture_type);
|
||||
INLINE TextureType get_texture_type() const;
|
||||
@ -215,6 +222,9 @@ PUBLISHED:
|
||||
INLINE void set_tex_gen(TexGen tex_gen);
|
||||
INLINE TexGen get_tex_gen() const;
|
||||
|
||||
INLINE void set_quality_level(QualityLevel quality_level);
|
||||
INLINE QualityLevel get_quality_level() const;
|
||||
|
||||
INLINE void set_stage_name(const string &stage_name);
|
||||
INLINE void clear_stage_name();
|
||||
INLINE bool has_stage_name() const;
|
||||
@ -281,6 +291,7 @@ PUBLISHED:
|
||||
static CombineSource string_combine_source(const string &string);
|
||||
static CombineOperand string_combine_operand(const string &string);
|
||||
static TexGen string_tex_gen(const string &string);
|
||||
static QualityLevel string_quality_level(const string &string);
|
||||
|
||||
public:
|
||||
virtual EggTransform *as_transform();
|
||||
@ -314,6 +325,7 @@ private:
|
||||
EnvType _env_type;
|
||||
bool _saved_result;
|
||||
TexGen _tex_gen;
|
||||
QualityLevel _quality_level;
|
||||
string _stage_name;
|
||||
int _priority;
|
||||
Colorf _color;
|
||||
@ -399,6 +411,7 @@ EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::CombineChannel cc
|
||||
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::CombineSource cs);
|
||||
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::CombineOperand co);
|
||||
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::TexGen tex_gen);
|
||||
EXPCL_PANDAEGG ostream &operator << (ostream &out, EggTexture::QualityLevel quality_level);
|
||||
|
||||
#include "eggTexture.I"
|
||||
|
||||
|
@ -537,11 +537,19 @@ texture_body:
|
||||
} else if (cmp_nocase_uh(name, "tex_gen") == 0) {
|
||||
EggTexture::TexGen tex_gen = EggTexture::string_tex_gen(strval);
|
||||
if (tex_gen == EggTexture::TG_unspecified) {
|
||||
eggyywarning("Unknown texture env type " + strval);
|
||||
eggyywarning("Unknown tex-gen " + strval);
|
||||
} else {
|
||||
texture->set_tex_gen(tex_gen);
|
||||
}
|
||||
|
||||
} else if (cmp_nocase_uh(name, "quality_level") == 0) {
|
||||
EggTexture::QualityLevel quality_level = EggTexture::string_quality_level(strval);
|
||||
if (quality_level == EggTexture::QL_unspecified) {
|
||||
eggyywarning("Unknown quality-level " + strval);
|
||||
} else {
|
||||
texture->set_quality_level(quality_level);
|
||||
}
|
||||
|
||||
} else if (cmp_nocase_uh(name, "stage_name") == 0) {
|
||||
texture->set_stage_name(strval);
|
||||
|
||||
|
@ -1261,6 +1261,25 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
|
||||
<< " for 4-component texture " << egg_tex->get_name() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
switch (egg_tex->get_quality_level()) {
|
||||
case EggTexture::QL_unspecified:
|
||||
case EggTexture::QL_default:
|
||||
tex->set_quality_level(Texture::QL_default);
|
||||
break;
|
||||
|
||||
case EggTexture::QL_fastest:
|
||||
tex->set_quality_level(Texture::QL_fastest);
|
||||
break;
|
||||
|
||||
case EggTexture::QL_normal:
|
||||
tex->set_quality_level(Texture::QL_normal);
|
||||
break;
|
||||
|
||||
case EggTexture::QL_best:
|
||||
tex->set_quality_level(Texture::QL_best);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -743,6 +743,17 @@ uses_mipmaps() const {
|
||||
return is_mipmap(get_minfilter());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_quality_level
|
||||
// Access: Public
|
||||
// Description: Returns the current quality_level hint. See
|
||||
// set_quality_level().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Texture::QualityLevel Texture::
|
||||
get_quality_level() const {
|
||||
return _quality_level;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::might_have_ram_image
|
||||
// Access: Published
|
||||
|
@ -42,6 +42,16 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
ConfigVariableEnum<Texture::QualityLevel> texture_quality_level
|
||||
("texture-quality-level", Texture::QL_normal,
|
||||
PRC_DESC("This specifies a global quality level for all textures. You "
|
||||
"may specify either fastest, normal, or best. This actually "
|
||||
"affects the meaning of Texture::set_quality_level(TQL_default), "
|
||||
"so it may be overridden on a per-texture basis. This generally "
|
||||
"only has an effect when using the tinydisplay software renderer; "
|
||||
"it has little or no effect on normal, hardware-accelerated "
|
||||
"renderers. See Texture::set_quality_level()."));
|
||||
|
||||
PStatCollector Texture::_texture_read_pcollector("*:Texture:Read");
|
||||
TypeHandle Texture::_type_handle;
|
||||
AutoTextureScale Texture::_textures_power_2 = ATS_UNSPECIFIED;
|
||||
@ -72,6 +82,7 @@ Texture(const string &name) :
|
||||
_ram_image_compression = CM_off;
|
||||
_render_to_texture = false;
|
||||
_match_framebuffer_format = false;
|
||||
_quality_level = QL_default;
|
||||
|
||||
_texture_type = TT_2d_texture;
|
||||
_x_size = 0;
|
||||
@ -129,6 +140,7 @@ Texture(const Texture ©) :
|
||||
_border_color(copy._border_color),
|
||||
_compression(copy._compression),
|
||||
_match_framebuffer_format(copy._match_framebuffer_format),
|
||||
_quality_level(copy._quality_level),
|
||||
_pad_x_size(copy._pad_x_size),
|
||||
_pad_y_size(copy._pad_y_size),
|
||||
_pad_z_size(copy._pad_z_size),
|
||||
@ -179,6 +191,7 @@ operator = (const Texture ©) {
|
||||
_border_color = copy._border_color;
|
||||
_compression = copy._compression;
|
||||
_match_framebuffer_format = copy._match_framebuffer_format;
|
||||
_quality_level = copy._quality_level;
|
||||
_ram_image_compression = copy._ram_image_compression;
|
||||
_ram_images = copy._ram_images;
|
||||
++_properties_modified;
|
||||
@ -838,6 +851,23 @@ set_render_to_texture(bool render_to_texture) {
|
||||
_render_to_texture = render_to_texture;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::set_quality_level
|
||||
// Access: Public
|
||||
// Description: Sets a hint to the renderer about the desired
|
||||
// performance / quality tradeoff for this particular
|
||||
// texture. This is most useful for the tinydisplay
|
||||
// software renderer; for normal, hardware-accelerated
|
||||
// renderers, this may have little or no effect.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Texture::
|
||||
set_quality_level(Texture::QualityLevel quality_level) {
|
||||
if (_quality_level != quality_level) {
|
||||
++_properties_modified;
|
||||
_quality_level = quality_level;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::get_expected_num_mipmap_levels
|
||||
// Access: Published
|
||||
@ -3539,6 +3569,9 @@ fillin(DatagramIterator &scan, BamReader *manager, bool has_rawdata) {
|
||||
if (manager->get_file_minor_ver() >= 1) {
|
||||
set_compression((CompressionMode)scan.get_uint8());
|
||||
}
|
||||
if (manager->get_file_minor_ver() >= 16) {
|
||||
set_quality_level((QualityLevel)scan.get_uint8());
|
||||
}
|
||||
|
||||
Format format = (Format)scan.get_uint8();
|
||||
int num_components = scan.get_uint8();
|
||||
@ -3696,6 +3729,7 @@ write_datagram(BamWriter *manager, Datagram &me) {
|
||||
me.add_int16(_anisotropic_degree);
|
||||
_border_color.write_datagram(me);
|
||||
me.add_uint8(_compression);
|
||||
me.add_uint8(_quality_level);
|
||||
|
||||
me.add_uint8(_format);
|
||||
me.add_uint8(_num_components);
|
||||
@ -3927,3 +3961,51 @@ operator << (ostream &out, Texture::CompressionMode cm) {
|
||||
return out << "(**invalid Texture::CompressionMode(" << (int)cm << ")**)";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::QualityLevel output operator
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ostream &
|
||||
operator << (ostream &out, Texture::QualityLevel tql) {
|
||||
switch (tql) {
|
||||
case Texture::QL_default:
|
||||
return out << "default";
|
||||
case Texture::QL_fastest:
|
||||
return out << "fastest";
|
||||
case Texture::QL_normal:
|
||||
return out << "normal";
|
||||
case Texture::QL_best:
|
||||
return out << "best";
|
||||
}
|
||||
|
||||
return out << "**invalid Texture::QualityLevel (" << (int)tql << ")**";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Texture::QualityLevel input operator
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
istream &
|
||||
operator >> (istream &in, Texture::QualityLevel &tql) {
|
||||
string word;
|
||||
in >> word;
|
||||
|
||||
if (cmp_nocase(word, "default") == 0) {
|
||||
tql = Texture::QL_default;
|
||||
|
||||
} else if (cmp_nocase(word, "fastest") == 0) {
|
||||
tql = Texture::QL_fastest;
|
||||
|
||||
} else if (cmp_nocase(word, "normal") == 0) {
|
||||
tql = Texture::QL_normal;
|
||||
|
||||
} else if (cmp_nocase(word, "best") == 0) {
|
||||
tql = Texture::QL_best;
|
||||
|
||||
} else {
|
||||
gobj_cat->error() << "Invalid Texture::QualityLevel value: " << word << "\n";
|
||||
tql = Texture::QL_default;
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
@ -175,6 +175,13 @@ PUBLISHED:
|
||||
CM_dxt5,
|
||||
};
|
||||
|
||||
enum QualityLevel {
|
||||
QL_default, // according to texture-quality-level
|
||||
QL_fastest,
|
||||
QL_normal,
|
||||
QL_best,
|
||||
};
|
||||
|
||||
PUBLISHED:
|
||||
Texture(const string &name = string());
|
||||
protected:
|
||||
@ -271,6 +278,9 @@ PUBLISHED:
|
||||
INLINE bool get_render_to_texture() const;
|
||||
INLINE bool uses_mipmaps() const;
|
||||
|
||||
void set_quality_level(QualityLevel quality_level);
|
||||
INLINE QualityLevel get_quality_level() const;
|
||||
|
||||
int get_expected_num_mipmap_levels() const;
|
||||
int get_expected_mipmap_x_size(int n) const;
|
||||
int get_expected_mipmap_y_size(int n) const;
|
||||
@ -515,6 +525,7 @@ protected:
|
||||
CompressionMode _compression;
|
||||
bool _render_to_texture;
|
||||
bool _match_framebuffer_format;
|
||||
QualityLevel _quality_level;
|
||||
|
||||
int _pad_x_size;
|
||||
int _pad_y_size;
|
||||
@ -587,6 +598,8 @@ private:
|
||||
friend class TexturePool;
|
||||
};
|
||||
|
||||
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<Texture::QualityLevel> texture_quality_level;
|
||||
|
||||
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::TextureType tt);
|
||||
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::ComponentType ct);
|
||||
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::Format f);
|
||||
@ -598,6 +611,8 @@ EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::WrapMode wm);
|
||||
EXPCL_PANDA_GOBJ istream &operator >> (istream &in, Texture::WrapMode &wm);
|
||||
|
||||
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::CompressionMode cm);
|
||||
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::QualityLevel tql);
|
||||
EXPCL_PANDA_GOBJ istream &operator >> (istream &in, Texture::QualityLevel &tql);
|
||||
|
||||
#include "texture.I"
|
||||
|
||||
|
@ -36,7 +36,7 @@ static const unsigned short _bam_major_ver = 6;
|
||||
// Bumped to major version 5 on 5/6/05 for new Geom implementation.
|
||||
// Bumped to major version 6 on 2/11/06 to factor out PandaNode::CData.
|
||||
|
||||
static const unsigned short _bam_minor_ver = 15;
|
||||
static const unsigned short _bam_minor_ver = 16;
|
||||
// Bumped to minor version 1 on 3/12/06 to add Texture::_compression.
|
||||
// Bumped to minor version 2 on 3/17/06 to add PandaNode::_draw_control_mask.
|
||||
// Bumped to minor version 3 on 3/21/06 to add Texture::_ram_images.
|
||||
@ -52,6 +52,7 @@ static const unsigned short _bam_minor_ver = 15;
|
||||
// Bumped to minor version 13 on 8/15/07 to reverse CollisionPolygon vertices.
|
||||
// Bumped to minor version 14 on 12/19/07 to change default ColorAttrib.
|
||||
// Bumped to minor version 15 on 4/9/08 to add TextureAttrib::_implicit_sort.
|
||||
// Bumped to minor version 16 on 5/13/08 to add Texture::_quality_level.
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -37,6 +37,10 @@ DynamicTextPage(DynamicTextFont *font, int page_number) :
|
||||
// it by default.
|
||||
_compression = CM_off;
|
||||
|
||||
// It's usually pretty important for text to look its best, and it
|
||||
// doesn't usually have a high fill factor.
|
||||
set_quality_level(Texture::QL_best);
|
||||
|
||||
_x_size = _font->get_page_x_size();
|
||||
_y_size = _font->get_page_y_size();
|
||||
|
||||
|
@ -33,7 +33,6 @@ void gl_transform_to_viewport(GLContext *c,GLVertex *v)
|
||||
+ ZB_POINT_ALPHA_MIN);
|
||||
|
||||
/* texture */
|
||||
|
||||
if (c->texture_2d_enabled) {
|
||||
v->zp.s = (int)(v->tex_coord.X * c->current_texture->s_max);
|
||||
v->zp.t = (int)(v->tex_coord.Y * c->current_texture->t_max);
|
||||
|
@ -599,7 +599,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
}
|
||||
}
|
||||
|
||||
if (_c->texture_2d_enabled && _texture_replace) {
|
||||
if (_texturing_state != 0 && _texture_replace) {
|
||||
// We don't need the vertex color or lighting calculation after
|
||||
// all, since the current texture will just hide all of that.
|
||||
needs_color = false;
|
||||
@ -763,13 +763,14 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
}
|
||||
}
|
||||
|
||||
int texturing_state = 0; // untextured
|
||||
int texfilter_state = 0; // nearest
|
||||
if (_c->texture_2d_enabled) {
|
||||
int texturing_state = _texturing_state;
|
||||
int texfilter_state = 0; // tnearest
|
||||
if (texturing_state > 0) {
|
||||
texfilter_state = _texfilter_state;
|
||||
texturing_state = 2; // perspective-correct textures
|
||||
if (_c->matrix_model_projection_no_w_transform || !td_perspective_textures) {
|
||||
texturing_state = 1; // non-perspective-correct textures
|
||||
if (_c->matrix_model_projection_no_w_transform) {
|
||||
// Don't bother with the perspective-correct algorithm if we're
|
||||
// under an orthonormal lens, e.g. render2d.
|
||||
texturing_state = 1; // textured (not perspective correct)
|
||||
}
|
||||
|
||||
if (_texture_replace) {
|
||||
@ -1241,10 +1242,7 @@ release_texture(TextureContext *tc) {
|
||||
GLTexture *gltex = gtc->_gltex;
|
||||
gtc->_gltex = NULL;
|
||||
|
||||
if (_c->current_texture == gltex) {
|
||||
_c->current_texture = NULL;
|
||||
_c->texture_2d_enabled = false;
|
||||
}
|
||||
_texturing_state = 0; // just in case
|
||||
|
||||
for (int i = 0; i < gltex->num_levels; ++i) {
|
||||
gl_free(gltex->levels[i].pixmap);
|
||||
@ -1602,6 +1600,7 @@ do_issue_material() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TinyGraphicsStateGuardian::
|
||||
do_issue_texture() {
|
||||
_texturing_state = 0; // untextured
|
||||
_c->texture_2d_enabled = false;
|
||||
|
||||
int num_stages = _effective_texture->get_num_on_ff_stages();
|
||||
@ -1622,12 +1621,53 @@ do_issue_texture() {
|
||||
}
|
||||
|
||||
// Then, turn on the current texture mode.
|
||||
apply_texture(tc);
|
||||
if (!apply_texture(tc)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set a few state cache values.
|
||||
_texfilter_state = 0; // nearest
|
||||
if (texture->uses_mipmaps() && !td_ignore_mipmaps) {
|
||||
_texfilter_state = 1; // mipmap
|
||||
_c->texture_2d_enabled = true;
|
||||
|
||||
_texturing_state = 2; // perspective (perspective-correct texturing)
|
||||
if (!td_perspective_textures) {
|
||||
_texturing_state = 1; // textured (not perspective correct)
|
||||
}
|
||||
|
||||
Texture::QualityLevel quality_level = texture->get_quality_level();
|
||||
if (quality_level == Texture::QL_default) {
|
||||
quality_level = texture_quality_level;
|
||||
}
|
||||
|
||||
if (quality_level == Texture::QL_best) {
|
||||
// This is the most generic texture filter. Slow, but pretty.
|
||||
_texfilter_state = 2; // tgeneral
|
||||
_c->zb->tex_minfilter_func = get_tex_filter_func(texture->get_minfilter());
|
||||
_c->zb->tex_magfilter_func = get_tex_filter_func(texture->get_magfilter());
|
||||
|
||||
if (texture->get_minfilter() == Texture::FT_nearest &&
|
||||
texture->get_magfilter() == Texture::FT_nearest) {
|
||||
// This case is inlined.
|
||||
_texfilter_state = 0; // tnearest
|
||||
} else if (texture->get_minfilter() == Texture::FT_nearest_mipmap_nearest &&
|
||||
texture->get_magfilter() == Texture::FT_nearest) {
|
||||
// So is this case.
|
||||
_texfilter_state = 1; // tmipmap
|
||||
}
|
||||
|
||||
} else if (quality_level == Texture::QL_fastest) {
|
||||
// This is the cheapest texture filter. We disallow mipmaps and
|
||||
// perspective correctness.
|
||||
_texfilter_state = 0; // tnearest
|
||||
_texturing_state = 1; // textured (not perspective correct)
|
||||
|
||||
} else {
|
||||
// This is the default texture filter. We use nearest sampling if
|
||||
// there are no mipmaps, and mipmap_nearest if there are any
|
||||
// mipmaps--these are the two inlined filters.
|
||||
_texfilter_state = 0; // tnearest
|
||||
if (texture->uses_mipmaps() && !td_ignore_mipmaps) {
|
||||
_texfilter_state = 1; // tmipmap
|
||||
}
|
||||
}
|
||||
|
||||
// M_replace means M_replace; anything else is treated the same as
|
||||
@ -1642,29 +1682,32 @@ do_issue_texture() {
|
||||
// texture, and makes it the current texture available
|
||||
// for rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TinyGraphicsStateGuardian::
|
||||
bool TinyGraphicsStateGuardian::
|
||||
apply_texture(TextureContext *tc) {
|
||||
TinyTextureContext *gtc = DCAST(TinyTextureContext, tc);
|
||||
|
||||
gtc->set_active(true);
|
||||
_c->current_texture = gtc->_gltex;
|
||||
_c->texture_2d_enabled = true;
|
||||
|
||||
GLTexture *gltex = gtc->_gltex;
|
||||
|
||||
if (gtc->was_image_modified() || gltex->num_levels == 0) {
|
||||
// If the texture image was modified, reload the texture.
|
||||
if (!upload_texture(gtc)) {
|
||||
bool okflag = upload_texture(gtc);
|
||||
if (!okflag) {
|
||||
tinydisplay_cat.error()
|
||||
<< "Could not load " << *gtc->get_texture()
|
||||
<< ": inappropriate size.\n";
|
||||
_c->texture_2d_enabled = false;
|
||||
}
|
||||
gtc->mark_loaded();
|
||||
if (!okflag) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
gtc->enqueue_lru(&_textures_lru);
|
||||
|
||||
_c->current_texture = gltex;
|
||||
_c->zb->current_texture = gltex->levels;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -2211,3 +2254,48 @@ get_color_blend_op(ColorBlendAttrib::Operand operand) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TinyGraphicsStateGuardian::get_tex_filter_func
|
||||
// Access: Private, Static
|
||||
// Description: Returns the pointer to the appropriate filter
|
||||
// function according to the texture's filter type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ZB_lookupTextureFunc TinyGraphicsStateGuardian::
|
||||
get_tex_filter_func(Texture::FilterType filter) {
|
||||
switch (filter) {
|
||||
case Texture::FT_nearest:
|
||||
return &lookup_texture_nearest;
|
||||
|
||||
case Texture::FT_linear:
|
||||
return &lookup_texture_bilinear;
|
||||
|
||||
case Texture::FT_nearest_mipmap_nearest:
|
||||
if (td_ignore_mipmaps) {
|
||||
return &lookup_texture_nearest;
|
||||
}
|
||||
return &lookup_texture_mipmap_nearest;
|
||||
|
||||
case Texture::FT_nearest_mipmap_linear:
|
||||
if (td_ignore_mipmaps) {
|
||||
return &lookup_texture_nearest;
|
||||
}
|
||||
return &lookup_texture_mipmap_linear;
|
||||
|
||||
case Texture::FT_linear_mipmap_nearest:
|
||||
if (td_ignore_mipmaps) {
|
||||
return &lookup_texture_bilinear;
|
||||
}
|
||||
return &lookup_texture_mipmap_bilinear;
|
||||
|
||||
case Texture::FT_linear_mipmap_linear:
|
||||
if (td_ignore_mipmaps) {
|
||||
return &lookup_texture_bilinear;
|
||||
}
|
||||
return &lookup_texture_mipmap_trilinear;
|
||||
|
||||
default:
|
||||
return &lookup_texture_nearest;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ private:
|
||||
void do_issue_material();
|
||||
void do_issue_texture();
|
||||
|
||||
void apply_texture(TextureContext *tc);
|
||||
bool apply_texture(TextureContext *tc);
|
||||
bool upload_texture(TinyTextureContext *gtc);
|
||||
bool setup_gltex(GLTexture *gltex, int x_size, int y_size, int num_levels);
|
||||
int get_tex_shift(int orig_size);
|
||||
@ -119,6 +119,7 @@ private:
|
||||
void setup_material(GLMaterial *gl_material, const Material *material);
|
||||
static void load_matrix(M4 *matrix, const TransformState *transform);
|
||||
static int get_color_blend_op(ColorBlendAttrib::Operand operand);
|
||||
static ZB_lookupTextureFunc get_tex_filter_func(Texture::FilterType filter);
|
||||
|
||||
public:
|
||||
// Filled in by the Tiny*GraphicsWindow at begin_frame().
|
||||
@ -136,6 +137,7 @@ private:
|
||||
CMF_diffuse = 0x002,
|
||||
};
|
||||
int _color_material_flags;
|
||||
int _texturing_state;
|
||||
int _texfilter_state;
|
||||
bool _texture_replace;
|
||||
|
||||
|
@ -509,6 +509,9 @@ TinyOsxGraphicsWindow::TinyOsxGraphicsWindow(GraphicsPipe *pipe,
|
||||
_cursor_hidden = false;
|
||||
_display_hide_cursor = false;
|
||||
_wheel_delta = 0;
|
||||
|
||||
_frame_buffer = NULL;
|
||||
update_pixel_factor();
|
||||
|
||||
if (tinydisplay_cat.is_debug())
|
||||
tinydisplay_cat.debug() << "TinyOsxGraphicsWindow::TinyOsxGraphicsWindow() -" <<_ID << "\n";
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "zbuffer.h"
|
||||
#include "pnotify.h"
|
||||
|
||||
ZBuffer *ZB_open(int xsize, int ysize, int mode,
|
||||
int nb_colors,
|
||||
@ -343,8 +344,26 @@ void ZB_clear_viewport(ZBuffer * zb, int clear_z, ZPOINT z,
|
||||
#define ZB_ST_FRAC_HIGH (1 << ZB_POINT_ST_FRAC_BITS)
|
||||
#define ZB_ST_FRAC_MASK (ZB_ST_FRAC_HIGH - 1)
|
||||
|
||||
PIXEL lookup_texture_bilinear(ZTextureLevel *base_level, int s, int t)
|
||||
#define LINEAR_FILTER_BITSIZE(c1, c2, f, bitsize) \
|
||||
((((c2) * (f)) >> bitsize) + (((c1) * ((1 << bitsize) - (f))) >> bitsize))
|
||||
|
||||
#define LINEAR_FILTER(c1, c2, f) \
|
||||
LINEAR_FILTER_BITSIZE(c1, c2, f, ZB_POINT_ST_FRAC_BITS)
|
||||
|
||||
#define BILINEAR_FILTER(c1, c2, c3, c4, sf, tf) \
|
||||
(LINEAR_FILTER(LINEAR_FILTER(c1, c2, sf), LINEAR_FILTER(c3, c4, sf), tf))
|
||||
|
||||
// Grab the nearest texel from the base level. This is also
|
||||
// implemented inline as ZB_LOOKUP_TEXTURE_NEAREST.
|
||||
PIXEL lookup_texture_nearest(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx)
|
||||
{
|
||||
return ZB_LOOKUP_TEXTURE_NEAREST(texture_levels, s, t);
|
||||
}
|
||||
|
||||
// Bilinear filter four texels in the base level.
|
||||
PIXEL lookup_texture_bilinear(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx)
|
||||
{
|
||||
ZTextureLevel *base_level = texture_levels;
|
||||
PIXEL p1, p2, p3, p4;
|
||||
int sf, tf;
|
||||
int r, g, b, a;
|
||||
@ -356,18 +375,127 @@ PIXEL lookup_texture_bilinear(ZTextureLevel *base_level, int s, int t)
|
||||
p3 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, s, t + ZB_ST_FRAC_HIGH);
|
||||
p4 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, s + ZB_ST_FRAC_HIGH, t + ZB_ST_FRAC_HIGH);
|
||||
tf = t & ZB_ST_FRAC_MASK;
|
||||
|
||||
r = (((PIXEL_R(p4) * sf + PIXEL_R(p3) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * tf +
|
||||
((PIXEL_R(p2) * sf + PIXEL_R(p1) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * (ZB_ST_FRAC_HIGH - tf)) >> ZB_POINT_ST_FRAC_BITS;
|
||||
|
||||
g = (((PIXEL_G(p4) * sf + PIXEL_G(p3) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * tf +
|
||||
((PIXEL_G(p2) * sf + PIXEL_G(p1) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * (ZB_ST_FRAC_HIGH - tf)) >> ZB_POINT_ST_FRAC_BITS;
|
||||
|
||||
b = (((PIXEL_B(p4) * sf + PIXEL_B(p3) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * tf +
|
||||
((PIXEL_B(p2) * sf + PIXEL_B(p1) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * (ZB_ST_FRAC_HIGH - tf)) >> ZB_POINT_ST_FRAC_BITS;
|
||||
|
||||
a = (((PIXEL_A(p4) * sf + PIXEL_A(p3) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * tf +
|
||||
((PIXEL_A(p2) * sf + PIXEL_A(p1) * (ZB_ST_FRAC_HIGH - sf)) >> ZB_POINT_ST_FRAC_BITS) * (ZB_ST_FRAC_HIGH - tf)) >> ZB_POINT_ST_FRAC_BITS;
|
||||
r = BILINEAR_FILTER(PIXEL_R(p1), PIXEL_R(p2), PIXEL_R(p3), PIXEL_R(p4), sf, tf);
|
||||
g = BILINEAR_FILTER(PIXEL_G(p1), PIXEL_G(p2), PIXEL_G(p3), PIXEL_G(p4), sf, tf);
|
||||
b = BILINEAR_FILTER(PIXEL_B(p1), PIXEL_B(p2), PIXEL_B(p3), PIXEL_B(p4), sf, tf);
|
||||
a = BILINEAR_FILTER(PIXEL_A(p1), PIXEL_A(p2), PIXEL_A(p3), PIXEL_A(p4), sf, tf);
|
||||
|
||||
return RGBA_TO_PIXEL(r, g, b, a);
|
||||
}
|
||||
|
||||
// Grab the nearest texel from the nearest mipmap level. This is also
|
||||
// implemented inline as ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST.
|
||||
PIXEL lookup_texture_mipmap_nearest(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx)
|
||||
{
|
||||
return ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_levels, s, t, level);
|
||||
}
|
||||
|
||||
// Linear filter the two texels from the two nearest mipmap levels.
|
||||
PIXEL lookup_texture_mipmap_linear(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx)
|
||||
{
|
||||
PIXEL p1, p2;
|
||||
int r, g, b, a;
|
||||
|
||||
p1 = ZB_LOOKUP_TEXTURE_NEAREST(texture_levels + level - 1, s >> (level - 1), t >> (level - 1));
|
||||
p2 = ZB_LOOKUP_TEXTURE_NEAREST(texture_levels + level, s >> level, t >> level);
|
||||
|
||||
unsigned int bitsize = (level - 1) + ZB_POINT_ST_FRAC_BITS;
|
||||
r = LINEAR_FILTER_BITSIZE(PIXEL_R(p1), PIXEL_R(p2), level_dx, bitsize);
|
||||
g = LINEAR_FILTER_BITSIZE(PIXEL_G(p1), PIXEL_G(p2), level_dx, bitsize);
|
||||
b = LINEAR_FILTER_BITSIZE(PIXEL_B(p1), PIXEL_B(p2), level_dx, bitsize);
|
||||
a = LINEAR_FILTER_BITSIZE(PIXEL_A(p1), PIXEL_A(p2), level_dx, bitsize);
|
||||
|
||||
return RGBA_TO_PIXEL(r, g, b, a);
|
||||
}
|
||||
|
||||
// Bilinear filter four texels in the nearest mipmap level.
|
||||
PIXEL lookup_texture_mipmap_bilinear(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx)
|
||||
{
|
||||
ZTextureLevel *base_level = texture_levels + level;
|
||||
s >>= level;
|
||||
t >>= level;
|
||||
|
||||
PIXEL p1, p2, p3, p4;
|
||||
int sf, tf;
|
||||
int r, g, b, a;
|
||||
|
||||
p1 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, s, t);
|
||||
p2 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, s + ZB_ST_FRAC_HIGH, t);
|
||||
sf = s & ZB_ST_FRAC_MASK;
|
||||
|
||||
p3 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, s, t + ZB_ST_FRAC_HIGH);
|
||||
p4 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, s + ZB_ST_FRAC_HIGH, t + ZB_ST_FRAC_HIGH);
|
||||
tf = t & ZB_ST_FRAC_MASK;
|
||||
|
||||
r = BILINEAR_FILTER(PIXEL_R(p1), PIXEL_R(p2), PIXEL_R(p3), PIXEL_R(p4), sf, tf);
|
||||
g = BILINEAR_FILTER(PIXEL_G(p1), PIXEL_G(p2), PIXEL_G(p3), PIXEL_G(p4), sf, tf);
|
||||
b = BILINEAR_FILTER(PIXEL_B(p1), PIXEL_B(p2), PIXEL_B(p3), PIXEL_B(p4), sf, tf);
|
||||
a = BILINEAR_FILTER(PIXEL_A(p1), PIXEL_A(p2), PIXEL_A(p3), PIXEL_A(p4), sf, tf);
|
||||
|
||||
return RGBA_TO_PIXEL(r, g, b, a);
|
||||
}
|
||||
|
||||
// Bilinear filter four texels in each of the nearest two mipmap
|
||||
// levels, then linear filter them together.
|
||||
PIXEL lookup_texture_mipmap_trilinear(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx)
|
||||
{
|
||||
PIXEL p1a, p2a;
|
||||
|
||||
{
|
||||
ZTextureLevel *base_level = texture_levels + level - 1;
|
||||
int sl = s >> (level - 1);
|
||||
int tl = t >> (level - 1);
|
||||
|
||||
PIXEL p1, p2, p3, p4;
|
||||
int sf, tf;
|
||||
int r, g, b, a;
|
||||
|
||||
p1 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, sl, tl);
|
||||
p2 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, sl + ZB_ST_FRAC_HIGH, tl);
|
||||
sf = sl & ZB_ST_FRAC_MASK;
|
||||
|
||||
p3 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, sl, tl + ZB_ST_FRAC_HIGH);
|
||||
p4 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, sl + ZB_ST_FRAC_HIGH, tl + ZB_ST_FRAC_HIGH);
|
||||
tf = tl & ZB_ST_FRAC_MASK;
|
||||
|
||||
r = BILINEAR_FILTER(PIXEL_R(p1), PIXEL_R(p2), PIXEL_R(p3), PIXEL_R(p4), sf, tf);
|
||||
g = BILINEAR_FILTER(PIXEL_G(p1), PIXEL_G(p2), PIXEL_G(p3), PIXEL_G(p4), sf, tf);
|
||||
b = BILINEAR_FILTER(PIXEL_B(p1), PIXEL_B(p2), PIXEL_B(p3), PIXEL_B(p4), sf, tf);
|
||||
a = BILINEAR_FILTER(PIXEL_A(p1), PIXEL_A(p2), PIXEL_A(p3), PIXEL_A(p4), sf, tf);
|
||||
p1a = RGBA_TO_PIXEL(r, g, b, a);
|
||||
}
|
||||
|
||||
{
|
||||
ZTextureLevel *base_level = texture_levels + level;
|
||||
int sl = s >> level;
|
||||
int tl = t >> level;
|
||||
|
||||
PIXEL p1, p2, p3, p4;
|
||||
int sf, tf;
|
||||
int r, g, b, a;
|
||||
|
||||
p1 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, sl, tl);
|
||||
p2 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, sl + ZB_ST_FRAC_HIGH, tl);
|
||||
sf = sl & ZB_ST_FRAC_MASK;
|
||||
|
||||
p3 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, sl, tl + ZB_ST_FRAC_HIGH);
|
||||
p4 = ZB_LOOKUP_TEXTURE_NEAREST(base_level, sl + ZB_ST_FRAC_HIGH, tl + ZB_ST_FRAC_HIGH);
|
||||
tf = tl & ZB_ST_FRAC_MASK;
|
||||
|
||||
r = BILINEAR_FILTER(PIXEL_R(p1), PIXEL_R(p2), PIXEL_R(p3), PIXEL_R(p4), sf, tf);
|
||||
g = BILINEAR_FILTER(PIXEL_G(p1), PIXEL_G(p2), PIXEL_G(p3), PIXEL_G(p4), sf, tf);
|
||||
b = BILINEAR_FILTER(PIXEL_B(p1), PIXEL_B(p2), PIXEL_B(p3), PIXEL_B(p4), sf, tf);
|
||||
a = BILINEAR_FILTER(PIXEL_A(p1), PIXEL_A(p2), PIXEL_A(p3), PIXEL_A(p4), sf, tf);
|
||||
p2a = RGBA_TO_PIXEL(r, g, b, a);
|
||||
}
|
||||
|
||||
int r, g, b, a;
|
||||
unsigned int bitsize = (level - 1) + ZB_POINT_ST_FRAC_BITS;
|
||||
r = LINEAR_FILTER_BITSIZE(PIXEL_R(p1a), PIXEL_R(p2a), level_dx, bitsize);
|
||||
g = LINEAR_FILTER_BITSIZE(PIXEL_G(p1a), PIXEL_G(p2a), level_dx, bitsize);
|
||||
b = LINEAR_FILTER_BITSIZE(PIXEL_B(p1a), PIXEL_B(p2a), level_dx, bitsize);
|
||||
a = LINEAR_FILTER_BITSIZE(PIXEL_A(p1a), PIXEL_A(p2a), level_dx, bitsize);
|
||||
|
||||
return RGBA_TO_PIXEL(r, g, b, a);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ typedef unsigned short ZPOINT;
|
||||
#define ZB_LOOKUP_TEXTURE_NEAREST(texture_levels, s, t) \
|
||||
(texture_levels)->pixmap[ZB_TEXEL(texture_levels, s, t)]
|
||||
|
||||
#define ZB_LOOKUP_TEXTURE_NEAREST_MIPMAP(texture_levels, s, t, level) \
|
||||
#define ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_levels, s, t, level) \
|
||||
ZB_LOOKUP_TEXTURE_NEAREST((texture_levels) + (level), (s) >> (level), (t) >> (level))
|
||||
|
||||
/* A special abs() function which doesn't require any branching
|
||||
@ -44,15 +44,11 @@ typedef unsigned short ZPOINT;
|
||||
//#define FAST_ABS(v) (((v) ^ ((v) >> (sizeof(v) * 8 - 1))) - ((v) >> (sizeof(v) * 8 - 1)))
|
||||
|
||||
#define DO_CALC_MIPMAP_LEVEL \
|
||||
mipmap_level = get_next_higher_bit(((unsigned int)abs(dsdx) + (unsigned int)abs(dtdx)) >> ZB_POINT_ST_FRAC_BITS)
|
||||
|
||||
#if 0
|
||||
/* Experiment with bilinear filtering. Looks great, but seems to run
|
||||
about 25% slower. */
|
||||
#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level) \
|
||||
lookup_texture_bilinear((texture_levels), (s), (t))
|
||||
|
||||
#endif
|
||||
{ \
|
||||
mipmap_dx = ((unsigned int)abs(dsdx) + (unsigned int)abs(dtdx)); \
|
||||
mipmap_level = get_next_higher_bit(mipmap_dx >> ZB_POINT_ST_FRAC_BITS); \
|
||||
mipmap_dx &= ((1 << ((mipmap_level - 1) + ZB_POINT_ST_FRAC_BITS)) - 1); \
|
||||
}
|
||||
|
||||
#define ZB_POINT_RED_MIN 0x0000
|
||||
#define ZB_POINT_RED_MAX 0xffff
|
||||
@ -106,7 +102,9 @@ typedef struct ZBufferPoint ZBufferPoint;
|
||||
typedef void (*ZB_fillTriangleFunc)(ZBuffer *,
|
||||
ZBufferPoint *,ZBufferPoint *,ZBufferPoint *);
|
||||
|
||||
typedef void (*ZB_storePixelFunc) (ZBuffer *zb, PIXEL &result, int r, int g, int b, int a);
|
||||
typedef void (*ZB_storePixelFunc)(ZBuffer *zb, PIXEL &result, int r, int g, int b, int a);
|
||||
|
||||
typedef PIXEL (*ZB_lookupTextureFunc)(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx);
|
||||
|
||||
struct ZBuffer {
|
||||
int xsize,ysize;
|
||||
@ -124,6 +122,8 @@ struct ZBuffer {
|
||||
int reference_alpha;
|
||||
int blend_r, blend_g, blend_b, blend_a;
|
||||
ZB_storePixelFunc store_pix_func;
|
||||
ZB_lookupTextureFunc tex_minfilter_func;
|
||||
ZB_lookupTextureFunc tex_magfilter_func;
|
||||
};
|
||||
|
||||
struct ZBufferPoint {
|
||||
@ -152,7 +152,12 @@ void ZB_clear_viewport(ZBuffer * zb, int clear_z, ZPOINT z,
|
||||
int clear_color, unsigned int r, unsigned int g, unsigned int b, unsigned int a,
|
||||
int xmin, int ymin, int xsize, int ysize);
|
||||
|
||||
PIXEL lookup_texture_bilinear(ZTextureLevel *base_level, int s, int t);
|
||||
PIXEL lookup_texture_nearest(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx);
|
||||
PIXEL lookup_texture_bilinear(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx);
|
||||
PIXEL lookup_texture_mipmap_nearest(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx);
|
||||
PIXEL lookup_texture_mipmap_linear(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx);
|
||||
PIXEL lookup_texture_mipmap_bilinear(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx);
|
||||
PIXEL lookup_texture_mipmap_trilinear(ZTextureLevel *texture_levels, int s, int t, unsigned int level, unsigned int level_dx);
|
||||
|
||||
/* linesize is in BYTES */
|
||||
void ZB_copyFrameBuffer(ZBuffer *zb,void *buf,int linesize);
|
||||
|
@ -146,7 +146,7 @@ typedef struct GLContext {
|
||||
/* textures */
|
||||
GLTexture *current_texture;
|
||||
int texture_2d_enabled;
|
||||
|
||||
|
||||
/* matrix */
|
||||
M4 matrix_projection;
|
||||
M4 matrix_model_view;
|
||||
|
@ -34,7 +34,7 @@
|
||||
float tz1,dtzdx,dtzdy,dtzdl_min,dtzdl_max;
|
||||
#endif
|
||||
#if defined(INTERP_MIPMAP) && (defined(INTERP_ST) || defined(INTERP_STZ))
|
||||
int mipmap_level;
|
||||
unsigned int mipmap_dx, mipmap_level;
|
||||
#endif
|
||||
|
||||
EARLY_OUT();
|
||||
|
@ -24,7 +24,7 @@ Options = [
|
||||
[ 'znone', 'zless' ],
|
||||
|
||||
# texture filters
|
||||
[ 'nearest', 'mipmap' ],
|
||||
[ 'tnearest', 'tmipmap', 'tgeneral' ],
|
||||
]
|
||||
|
||||
# The various combinations of these options are explicit within
|
||||
@ -60,8 +60,9 @@ CodeTable = {
|
||||
'zless' : '#define ZCMP(zpix, z) ((ZPOINT)(zpix) < (ZPOINT)(z))',
|
||||
|
||||
# texture filters
|
||||
'nearest' : '#define CALC_MIPMAP_LEVEL\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level) ZB_LOOKUP_TEXTURE_NEAREST(texture_levels, s, t)',
|
||||
'mipmap' : '#define CALC_MIPMAP_LEVEL DO_CALC_MIPMAP_LEVEL\n#define INTERP_MIPMAP\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level) ZB_LOOKUP_TEXTURE_NEAREST_MIPMAP(texture_levels, s, t, level)',
|
||||
'tnearest' : '#define CALC_MIPMAP_LEVEL\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level, level_dx) ZB_LOOKUP_TEXTURE_NEAREST(texture_levels, s, t)',
|
||||
'tmipmap' : '#define CALC_MIPMAP_LEVEL DO_CALC_MIPMAP_LEVEL\n#define INTERP_MIPMAP\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level, level_dx) ZB_LOOKUP_TEXTURE_MIPMAP_NEAREST(texture_levels, s, t, level)',
|
||||
'tgeneral' : '#define CALC_MIPMAP_LEVEL DO_CALC_MIPMAP_LEVEL\n#define INTERP_MIPMAP\n#define ZB_LOOKUP_TEXTURE(texture_levels, s, t, level, level_dx) ((level == 0) ? zb->tex_magfilter_func(texture_levels, s, t, level, level_dx) : zb->tex_minfilter_func(texture_levels, s, t, level, level_dx))',
|
||||
}
|
||||
|
||||
ops = [0] * len(Options)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,3 @@
|
||||
/* This file is generated code--do not edit. See ztriangle.py. */
|
||||
|
||||
extern const ZB_fillTriangleFunc fill_tri_funcs[2][4][3][2][2][3][3];
|
||||
extern const ZB_fillTriangleFunc fill_tri_funcs[2][4][3][2][3][3][3];
|
||||
|
@ -129,7 +129,7 @@ static void FNAME(white_textured) (ZBuffer *zb,
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx); \
|
||||
if (ACMP(zb, PIXEL_A(tmp))) { \
|
||||
STORE_PIX(pp[_a], tmp, PIXEL_R(tmp), PIXEL_G(tmp), PIXEL_B(tmp), PIXEL_A(tmp)); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
@ -173,7 +173,7 @@ static void FNAME(flat_textured) (ZBuffer *zb,
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx); \
|
||||
int a = oa0 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
@ -232,7 +232,7 @@ static void FNAME(smooth_textured) (ZBuffer *zb,
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx); \
|
||||
int a = oa1 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
@ -293,7 +293,7 @@ static void FNAME(white_perspective) (ZBuffer *zb,
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx); \
|
||||
if (ACMP(zb, PIXEL_A(tmp))) { \
|
||||
STORE_PIX(pp[_a], tmp, PIXEL_R(tmp), PIXEL_G(tmp), PIXEL_B(tmp), PIXEL_A(tmp)); \
|
||||
STORE_Z(pz[_a], zz); \
|
||||
@ -408,7 +408,7 @@ static void FNAME(flat_perspective) (ZBuffer *zb,
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx); \
|
||||
int a = oa0 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
@ -541,7 +541,7 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
|
||||
{ \
|
||||
zz=z >> ZB_POINT_Z_FRAC_BITS; \
|
||||
if (ZCMP(pz[_a], zz)) { \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level); \
|
||||
tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx); \
|
||||
int a = oa1 * PIXEL_A(tmp) >> 16; \
|
||||
if (ACMP(zb, a)) { \
|
||||
STORE_PIX(pp[_a], \
|
||||
|
@ -406,6 +406,7 @@ run() {
|
||||
PT(EggData) egg_data = new EggData;
|
||||
_group = new EggGroup();
|
||||
egg_data->add_child(_group);
|
||||
append_command_comment(egg_data);
|
||||
|
||||
_vpool = new EggVertexPool("vpool");
|
||||
_group->add_child(_vpool);
|
||||
@ -446,7 +447,7 @@ run() {
|
||||
texture->write(texture->read_source_image());
|
||||
}
|
||||
|
||||
write_egg_file();
|
||||
egg_data->write_egg(get_output());
|
||||
|
||||
} else {
|
||||
// Pass the generated egg structure through egg-palettize, without
|
||||
@ -641,6 +642,7 @@ make_tref(PNMTextGlyph *glyph, int character) {
|
||||
tref->set_wrap_mode(EggTexture::WM_clamp);
|
||||
tref->set_minfilter(EggTexture::FT_linear_mipmap_linear);
|
||||
tref->set_magfilter(EggTexture::FT_linear);
|
||||
tref->set_quality_level(EggTexture::QL_best);
|
||||
|
||||
return tref;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ Palettizer *pal = (Palettizer *)NULL;
|
||||
// allows us to easily update egg-palettize to write out additional
|
||||
// information to its pi file, without having it increment the bam
|
||||
// version number for all bam and boo files anywhere in the world.
|
||||
int Palettizer::_pi_version = 17;
|
||||
int Palettizer::_pi_version = 18;
|
||||
// Updated to version 8 on 3/20/03 to remove extensions from texture key names.
|
||||
// Updated to version 9 on 4/13/03 to add a few properties in various places.
|
||||
// Updated to version 10 on 4/15/03 to add _alpha_file_channel.
|
||||
@ -52,6 +52,7 @@ int Palettizer::_pi_version = 17;
|
||||
// Updated to version 15 on 8/01/05 to make TextureImages be case-insensitive.
|
||||
// Updated to version 16 on 4/03/06 to add Palettizer::_cutout_mode et al.
|
||||
// Updated to version 17 on 3/02/07 to add TextureImage::_txa_wrap_u etc.
|
||||
// Updated to version 18 on 5/13/08 to add TextureProperties::_quality_level.
|
||||
|
||||
int Palettizer::_min_pi_version = 8;
|
||||
// Dropped support for versions 7 and below on 7/14/03.
|
||||
|
@ -43,6 +43,7 @@ TextureProperties() {
|
||||
_keep_format = false;
|
||||
_minfilter = EggTexture::FT_unspecified;
|
||||
_magfilter = EggTexture::FT_unspecified;
|
||||
_quality_level = EggTexture::QL_unspecified;
|
||||
_anisotropic_degree = 0;
|
||||
_color_type = (PNMFileType *)NULL;
|
||||
_alpha_type = (PNMFileType *)NULL;
|
||||
@ -61,6 +62,7 @@ TextureProperties(const TextureProperties ©) :
|
||||
_keep_format(copy._keep_format),
|
||||
_minfilter(copy._minfilter),
|
||||
_magfilter(copy._magfilter),
|
||||
_quality_level(copy._quality_level),
|
||||
_anisotropic_degree(copy._anisotropic_degree),
|
||||
_color_type(copy._color_type),
|
||||
_alpha_type(copy._alpha_type),
|
||||
@ -82,6 +84,7 @@ operator = (const TextureProperties ©) {
|
||||
_keep_format = copy._keep_format;
|
||||
_minfilter = copy._minfilter;
|
||||
_magfilter = copy._magfilter;
|
||||
_quality_level = copy._quality_level;
|
||||
_anisotropic_degree = copy._anisotropic_degree;
|
||||
_color_type = copy._color_type;
|
||||
_alpha_type = copy._alpha_type;
|
||||
@ -105,6 +108,7 @@ clear_basic() {
|
||||
|
||||
_minfilter = EggTexture::FT_unspecified;
|
||||
_magfilter = EggTexture::FT_unspecified;
|
||||
_quality_level = EggTexture::QL_unspecified;
|
||||
_anisotropic_degree = 0;
|
||||
}
|
||||
|
||||
@ -249,6 +253,7 @@ update_properties(const TextureProperties &other) {
|
||||
|
||||
_minfilter = union_filter(_minfilter, other._minfilter);
|
||||
_magfilter = union_filter(_magfilter, other._magfilter);
|
||||
_quality_level = union_quality_level(_quality_level, other._quality_level);
|
||||
|
||||
_anisotropic_degree = other._anisotropic_degree;
|
||||
|
||||
@ -494,6 +499,7 @@ update_egg_tex(EggTexture *egg_tex) const {
|
||||
egg_tex->set_format(_format);
|
||||
egg_tex->set_minfilter(_minfilter);
|
||||
egg_tex->set_magfilter(_minfilter);
|
||||
egg_tex->set_quality_level(_quality_level);
|
||||
egg_tex->set_anisotropic_degree(_anisotropic_degree);
|
||||
}
|
||||
|
||||
@ -510,6 +516,7 @@ egg_properties_match(const TextureProperties &other) const {
|
||||
return (_format == other._format &&
|
||||
_minfilter == other._minfilter &&
|
||||
_magfilter == other._magfilter &&
|
||||
_quality_level == other._quality_level &&
|
||||
_anisotropic_degree == other._anisotropic_degree);
|
||||
}
|
||||
|
||||
@ -529,6 +536,9 @@ operator < (const TextureProperties &other) const {
|
||||
if (_magfilter != other._magfilter) {
|
||||
return (int)_magfilter < (int)other._magfilter;
|
||||
}
|
||||
if (_quality_level != other._quality_level) {
|
||||
return (int)_quality_level < (int)other._quality_level;
|
||||
}
|
||||
if (_anisotropic_degree != other._anisotropic_degree) {
|
||||
return _anisotropic_degree < other._anisotropic_degree;
|
||||
}
|
||||
@ -553,6 +563,7 @@ operator == (const TextureProperties &other) const {
|
||||
return (_format == other._format &&
|
||||
_minfilter == other._minfilter &&
|
||||
_magfilter == other._magfilter &&
|
||||
_quality_level == other._quality_level &&
|
||||
_anisotropic_degree == other._anisotropic_degree &&
|
||||
_color_type == other._color_type &&
|
||||
(_color_type == (PNMFileType *)NULL ||
|
||||
@ -759,6 +770,21 @@ union_filter(EggTexture::FilterType a, EggTexture::FilterType b) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureProperties::union_quality_level
|
||||
// Access: Private, Static
|
||||
// Description: Returns the EggTexture quality level which is the
|
||||
// more specific of the two.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggTexture::QualityLevel TextureProperties::
|
||||
union_quality_level(EggTexture::QualityLevel a, EggTexture::QualityLevel b) {
|
||||
if ((int)a < (int)b) {
|
||||
return b;
|
||||
} else {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureProperties::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
@ -790,6 +816,7 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
|
||||
datagram.add_bool(_keep_format);
|
||||
datagram.add_int32((int)_minfilter);
|
||||
datagram.add_int32((int)_magfilter);
|
||||
datagram.add_int32((int)_quality_level);
|
||||
datagram.add_int32(_anisotropic_degree);
|
||||
writer->write_pointer(datagram, _color_type);
|
||||
writer->write_pointer(datagram, _alpha_type);
|
||||
@ -868,6 +895,9 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
}
|
||||
_minfilter = (EggTexture::FilterType)scan.get_int32();
|
||||
_magfilter = (EggTexture::FilterType)scan.get_int32();
|
||||
if (Palettizer::_read_pi_version >= 18) {
|
||||
_quality_level = (EggTexture::QualityLevel)scan.get_int32();
|
||||
}
|
||||
_anisotropic_degree = scan.get_int32();
|
||||
|
||||
manager->read_pointer(scan); // _color_type
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
bool _generic_format; // true if 'generic' keyword, meaning rgba8 -> rgba.
|
||||
bool _keep_format; // true if 'keep-format' keyword.
|
||||
EggTexture::FilterType _minfilter, _magfilter;
|
||||
EggTexture::QualityLevel _quality_level;
|
||||
int _anisotropic_degree;
|
||||
PNMFileType *_color_type;
|
||||
PNMFileType *_alpha_type;
|
||||
@ -82,6 +83,8 @@ private:
|
||||
|
||||
static EggTexture::FilterType union_filter(EggTexture::FilterType a,
|
||||
EggTexture::FilterType b);
|
||||
static EggTexture::QualityLevel union_quality_level(EggTexture::QualityLevel a,
|
||||
EggTexture::QualityLevel b);
|
||||
|
||||
bool _got_num_channels;
|
||||
int _num_channels;
|
||||
|
@ -106,6 +106,7 @@ from_egg(EggFile *egg_file, EggData *data, EggTexture *egg_tex) {
|
||||
_properties._format = _egg_tex->get_format();
|
||||
_properties._minfilter = _egg_tex->get_minfilter();
|
||||
_properties._magfilter = _egg_tex->get_magfilter();
|
||||
_properties._quality_level = _egg_tex->get_quality_level();
|
||||
_properties._anisotropic_degree = _egg_tex->get_anisotropic_degree();
|
||||
|
||||
string name = filename.get_basename_wo_extension();
|
||||
|
Loading…
x
Reference in New Issue
Block a user