Introduce ability to write older .bam versions, down to 6.21

See https://www.panda3d.org/manual/index.php/Dev:Bam_Format
This commit is contained in:
rdb 2016-04-29 16:30:41 +02:00
parent 063f9bbc4d
commit a2ae62dbda
27 changed files with 280 additions and 71 deletions

View File

@ -708,7 +708,10 @@ write_datagram(BamWriter *manager, Datagram &dg) {
dg.add_uint16(_stride);
dg.add_uint16(_total_bytes);
dg.add_uint8(_pad_to);
dg.add_uint16(_divisor);
if (manager->get_file_minor_ver() > 36) {
dg.add_uint16(_divisor);
}
consider_sort_columns();

View File

@ -378,9 +378,19 @@ write_datagram(BamWriter *manager, Datagram &dg) {
manager->write_pointer(dg, _name);
dg.add_uint8(_num_components);
dg.add_uint8(_numeric_type);
dg.add_uint8(_contents);
if (_contents == C_normal && manager->get_file_minor_ver() < 38) {
// Panda 1.9 did not have C_normal.
dg.add_uint8(C_vector);
} else {
dg.add_uint8(_contents);
}
dg.add_uint16(_start);
dg.add_uint8(_column_alignment);
if (manager->get_file_minor_ver() >= 29) {
dg.add_uint8(_column_alignment);
}
}
/**

View File

@ -257,7 +257,7 @@ set_roughness(PN_stdfloat roughness) {
// Calculate the specular exponent from the roughness as it is used in
// Blinn-Phong shading model. We use the popular Disney method of squaring
// the roughness to get a more perceptually linear scale. From:
// http:graphicrants.blogspot.de201308specular-brdf-reference.html
// http://graphicrants.blogspot.de/2013/08/specular-brdf-reference.html
if (roughness <= 0 || IS_NEARLY_ZERO(roughness)) {
_shininess = make_inf((PN_stdfloat)0);
} else {
@ -481,26 +481,35 @@ void Material::
write_datagram(BamWriter *manager, Datagram &me) {
me.add_string(get_name());
me.add_int32(_flags);
if (manager->get_file_minor_ver() >= 39) {
me.add_int32(_flags);
if (_flags & F_metallic) {
// Metalness workflow.
_base_color.write_datagram(me);
me.add_stdfloat(_metallic);
if (_flags & F_metallic) {
// Metalness workflow.
_base_color.write_datagram(me);
me.add_stdfloat(_metallic);
} else {
_ambient.write_datagram(me);
_diffuse.write_datagram(me);
_specular.write_datagram(me);
}
_emission.write_datagram(me);
if (_flags & F_roughness) {
me.add_stdfloat(_roughness);
} else {
me.add_stdfloat(_shininess);
}
me.add_stdfloat(_refractive_index);
} else {
_ambient.write_datagram(me);
_diffuse.write_datagram(me);
_specular.write_datagram(me);
}
_emission.write_datagram(me);
if (_flags & F_roughness) {
me.add_stdfloat(_roughness);
} else {
_emission.write_datagram(me);
me.add_stdfloat(_shininess);
me.add_int32(_flags & 0x7f);
}
me.add_stdfloat(_refractive_index);
}
/**

View File

@ -83,14 +83,18 @@ register_with_read_factory() {
*/
void MatrixLens::
write_datagram(BamWriter *manager, Datagram &dg) {
dg.add_uint8(_ml_flags);
_user_mat.write_datagram(dg);
Lens::write_datagram(manager, dg);
if (_ml_flags & MF_has_left_eye) {
_left_eye_mat.write_datagram(dg);
}
if (_ml_flags & MF_has_right_eye) {
_left_eye_mat.write_datagram(dg);
if (manager->get_file_minor_ver() >= 41) {
dg.add_uint8(_ml_flags);
_user_mat.write_datagram(dg);
if (_ml_flags & MF_has_left_eye) {
_left_eye_mat.write_datagram(dg);
}
if (_ml_flags & MF_has_right_eye) {
_left_eye_mat.write_datagram(dg);
}
}
}

View File

@ -8663,8 +8663,19 @@ do_write_datagram_header(CData *cdata, BamWriter *manager, Datagram &me, bool &h
me.add_uint8(cdata->_primary_file_num_channels);
me.add_uint8(cdata->_alpha_file_channel);
me.add_bool(has_rawdata);
me.add_uint8(cdata->_texture_type);
me.add_bool(cdata->_has_read_mipmaps);
if (manager->get_file_minor_ver() < 25 &&
cdata->_texture_type == TT_cube_map) {
// Between Panda3D releases 1.7.2 and 1.8.0 (bam versions 6.24 and 6.25),
// we added TT_2d_texture_array, shifting the definition for TT_cube_map.
me.add_uint8(TT_2d_texture_array);
} else {
me.add_uint8(cdata->_texture_type);
}
if (manager->get_file_minor_ver() >= 32) {
me.add_bool(cdata->_has_read_mipmaps);
}
}
/**
@ -8673,7 +8684,18 @@ do_write_datagram_header(CData *cdata, BamWriter *manager, Datagram &me, bool &h
*/
void Texture::
do_write_datagram_body(CData *cdata, BamWriter *manager, Datagram &me) {
cdata->_default_sampler.write_datagram(me);
if (manager->get_file_minor_ver() >= 36) {
cdata->_default_sampler.write_datagram(me);
} else {
const SamplerState &s = cdata->_default_sampler;
me.add_uint8(s.get_wrap_u());
me.add_uint8(s.get_wrap_v());
me.add_uint8(s.get_wrap_w());
me.add_uint8(s.get_minfilter());
me.add_uint8(s.get_magfilter());
me.add_int16(s.get_anisotropic_degree());
s.get_border_color().write_datagram(me);
}
me.add_uint8(cdata->_compression);
me.add_uint8(cdata->_quality_level);
@ -8685,7 +8707,9 @@ do_write_datagram_body(CData *cdata, BamWriter *manager, Datagram &me) {
me.add_uint8(cdata->_usage_hint);
}
me.add_uint8(cdata->_auto_texture_scale);
if (manager->get_file_minor_ver() >= 28) {
me.add_uint8(cdata->_auto_texture_scale);
}
me.add_uint32(cdata->_orig_file_x_size);
me.add_uint32(cdata->_orig_file_y_size);
@ -8711,11 +8735,15 @@ do_write_datagram_rawdata(CData *cdata, BamWriter *manager, Datagram &me) {
me.add_uint32(cdata->_y_size);
me.add_uint32(cdata->_z_size);
me.add_uint32(cdata->_pad_x_size);
me.add_uint32(cdata->_pad_y_size);
me.add_uint32(cdata->_pad_z_size);
if (manager->get_file_minor_ver() >= 30) {
me.add_uint32(cdata->_pad_x_size);
me.add_uint32(cdata->_pad_y_size);
me.add_uint32(cdata->_pad_z_size);
}
me.add_uint32(cdata->_num_views);
if (manager->get_file_minor_ver() >= 26) {
me.add_uint32(cdata->_num_views);
}
me.add_uint8(cdata->_component_type);
me.add_uint8(cdata->_component_width);
me.add_uint8(cdata->_ram_image_compression);

View File

@ -438,7 +438,10 @@ write_datagram(BamWriter *manager, Datagram &me) {
me.add_uint8(_rgb_scale);
me.add_uint8(_alpha_scale);
me.add_bool(_saved_result);
me.add_int32(_tex_view_offset);
if (manager->get_file_minor_ver() >= 26) {
me.add_int32(_tex_view_offset);
}
me.add_uint8(_combine_rgb_mode);
me.add_uint8(_num_combine_rgb_operands);

View File

@ -816,7 +816,10 @@ do_write_datagram_rawdata(Texture::CData *cdata_tex, BamWriter *manager, Datagra
CDReader cdata(_cycler);
dg.add_uint16(cdata_tex->_z_size);
dg.add_uint16(cdata_tex->_num_views);
if (manager->get_file_minor_ver() >= 26) {
dg.add_uint16(cdata_tex->_num_views);
}
nassertv(cdata->_pages.size() == (size_t)(cdata_tex->_z_size * cdata_tex->_num_views));
for (size_t n = 0; n < cdata->_pages.size(); ++n) {
const VideoPage &page = cdata->_pages[n];

View File

@ -872,18 +872,32 @@ write_datagram(BamWriter *manager, Datagram &dg) {
// write the number of off_planes
dg.add_uint16(get_num_off_planes());
// write the off planes pointers if any
Planes::const_iterator fi;
for (fi = _off_planes.begin(); fi != _off_planes.end(); ++fi) {
(*fi).write_datagram(manager, dg);
if (manager->get_file_minor_ver() < 40) {
for (fi = _off_planes.begin(); fi != _off_planes.end(); ++fi) {
manager->write_pointer(dg, fi->node());
}
} else {
for (fi = _off_planes.begin(); fi != _off_planes.end(); ++fi) {
(*fi).write_datagram(manager, dg);
}
}
// write the number of on planes
dg.add_uint16(get_num_on_planes());
// write the on planes pointers if any
Planes::const_iterator nti;
for (nti = _on_planes.begin(); nti != _on_planes.end(); ++nti) {
(*nti).write_datagram(manager, dg);
if (manager->get_file_minor_ver() < 40) {
for (nti = _on_planes.begin(); nti != _on_planes.end(); ++nti) {
manager->write_pointer(dg, nti->node());
}
} else {
for (nti = _on_planes.begin(); nti != _on_planes.end(); ++nti) {
(*nti).write_datagram(manager, dg);
}
}
}

View File

@ -162,8 +162,10 @@ write_datagram(BamWriter *manager, Datagram &dg) {
RenderAttrib::write_datagram(manager, dg);
dg.add_int32(_offset);
dg.add_stdfloat(_min_value);
dg.add_stdfloat(_max_value);
if (manager->get_file_minor_ver() >= 31) {
dg.add_stdfloat(_min_value);
dg.add_stdfloat(_max_value);
}
}
/**

View File

@ -206,9 +206,13 @@ fill_viz_geom(GeomNode *) {
*/
void Light::
write_datagram(BamWriter *manager, Datagram &dg) {
dg.add_bool(_has_color_temperature);
if (_has_color_temperature) {
dg.add_stdfloat(_color_temperature);
if (manager->get_file_minor_ver() >= 39) {
dg.add_bool(_has_color_temperature);
if (_has_color_temperature) {
dg.add_stdfloat(_color_temperature);
} else {
manager->write_cdata(dg, _cycler);
}
} else {
manager->write_cdata(dg, _cycler);
}

View File

@ -898,18 +898,31 @@ write_datagram(BamWriter *manager, Datagram &dg) {
// write the number of off_lights
dg.add_uint16(get_num_off_lights());
// write the off lights pointers if any
Lights::const_iterator fi;
for (fi = _off_lights.begin(); fi != _off_lights.end(); ++fi) {
(*fi).write_datagram(manager, dg);
if (manager->get_file_minor_ver() < 40) {
for (fi = _off_lights.begin(); fi != _off_lights.end(); ++fi) {
manager->write_pointer(dg, fi->node());
}
} else {
for (fi = _off_lights.begin(); fi != _off_lights.end(); ++fi) {
(*fi).write_datagram(manager, dg);
}
}
// write the number of on lights
dg.add_uint16(get_num_on_lights());
// write the on lights pointers if any
Lights::const_iterator nti;
for (nti = _on_lights.begin(); nti != _on_lights.end(); ++nti) {
(*nti).write_datagram(manager, dg);
if (manager->get_file_minor_ver() < 40) {
for (nti = _on_lights.begin(); nti != _on_lights.end(); ++nti) {
manager->write_pointer(dg, nti->node());
}
} else {
for (nti = _on_lights.begin(); nti != _on_lights.end(); ++nti) {
(*nti).write_datagram(manager, dg);
}
}
}

View File

@ -146,10 +146,17 @@ write_datagram(BamWriter *manager, Datagram &dg) {
// write the number of on occluders
dg.add_uint16(get_num_on_occluders());
// write the on occluders pointers if any
Occluders::const_iterator nti;
for (nti = _on_occluders.begin(); nti != _on_occluders.end(); ++nti) {
(*nti).write_datagram(manager, dg);
if (manager->get_file_minor_ver() < 40) {
for (nti = _on_occluders.begin(); nti != _on_occluders.end(); ++nti) {
manager->write_pointer(dg, nti->node());
}
} else {
for (nti = _on_occluders.begin(); nti != _on_occluders.end(); ++nti) {
(*nti).write_datagram(manager, dg);
}
}
}

View File

@ -40,7 +40,18 @@ register_with_read_factory() {
void ParamNodePath::
write_datagram(BamWriter *manager, Datagram &dg) {
ParamValueBase::write_datagram(manager, dg);
_node_path.write_datagram(manager, dg);
if (manager->get_file_minor_ver() < 40) {
// Before bam 6.40, we did not support writing NodePaths. Instaed, we
// write the PandaNode pointer and pray there is an unambiguous path.
if (_node_path.is_empty()) {
manager->write_pointer(dg, NULL);
} else {
manager->write_pointer(dg, _node_path.node());
}
} else {
_node_path.write_datagram(manager, dg);
}
}
/**

View File

@ -177,7 +177,9 @@ write_datagram(BamWriter *manager, Datagram &dg) {
RenderAttrib::write_datagram(manager, dg);
_frame.write_datagram(dg);
dg.add_bool(_off);
if (manager->get_file_minor_ver() >= 34) {
dg.add_bool(_off);
}
}
/**

View File

@ -338,8 +338,26 @@ void StencilAttrib::
write_datagram(BamWriter *manager, Datagram &dg) {
RenderAttrib::write_datagram(manager, dg);
for (int index = 0; index < SRS_total; ++index) {
dg.add_uint32(_stencil_render_states[index]);
if (manager->get_file_minor_ver() < 35) {
dg.add_int32(_stencil_render_states[SRS_front_comparison_function] != M_none);
dg.add_int32(_stencil_render_states[SRS_back_comparison_function] != M_none);
for (int index = 0; index < SRS_total; ++index) {
if (index == SRS_front_comparison_function ||
index == SRS_back_comparison_function) {
if (_stencil_render_states[index] == M_none) {
dg.add_uint32(7);
} else {
dg.add_uint32(_stencil_render_states[index] - 1);
}
} else {
dg.add_uint32(_stencil_render_states[index]);
}
}
} else {
for (int index = 0; index < SRS_total; ++index) {
dg.add_uint32(_stencil_render_states[index]);
}
}
}

View File

@ -461,7 +461,10 @@ write_datagram(BamWriter *manager, Datagram &dg) {
manager->write_pointer(dg, sn._stage);
manager->write_pointer(dg, sn._transform);
dg.add_int32(sn._override);
if (manager->get_file_minor_ver() >= 24) {
dg.add_int32(sn._override);
}
}
}

View File

@ -778,10 +778,16 @@ write_datagram(BamWriter *manager, Datagram &dg) {
manager->write_pointer(dg, stage);
manager->write_pointer(dg, tex);
dg.add_uint16((*si)._implicit_sort);
dg.add_int32((*si)._override);
dg.add_bool((*si)._has_sampler);
if ((*si)._has_sampler) {
(*si)._sampler.write_datagram(dg);
if (manager->get_file_minor_ver() >= 23) {
dg.add_int32((*si)._override);
}
if (manager->get_file_minor_ver() >= 36) {
dg.add_bool((*si)._has_sampler);
if ((*si)._has_sampler) {
(*si)._sampler.write_datagram(dg);
}
}
}
}

View File

@ -167,7 +167,9 @@ register_with_read_factory() {
void DirectionalLight::
write_datagram(BamWriter *manager, Datagram &dg) {
LightLensNode::write_datagram(manager, dg);
dg.add_bool(_has_specular_color);
if (manager->get_file_minor_ver() >= 39) {
dg.add_bool(_has_specular_color);
}
manager->write_cdata(dg, _cycler);
}

View File

@ -196,7 +196,9 @@ register_with_read_factory() {
void PointLight::
write_datagram(BamWriter *manager, Datagram &dg) {
LightLensNode::write_datagram(manager, dg);
dg.add_bool(_has_specular_color);
if (manager->get_file_minor_ver() >= 39) {
dg.add_bool(_has_specular_color);
}
manager->write_cdata(dg, _cycler);
}

View File

@ -252,7 +252,9 @@ register_with_read_factory() {
void Spotlight::
write_datagram(BamWriter *manager, Datagram &dg) {
LightLensNode::write_datagram(manager, dg);
dg.add_bool(_has_specular_color);
if (manager->get_file_minor_ver() >= 39) {
dg.add_bool(_has_specular_color);
}
manager->write_cdata(dg, _cycler);
}

View File

@ -53,8 +53,12 @@ write_datagram(BamWriter *manager, Datagram &dg) {
PandaNode::write_datagram(manager, dg);
dg.add_stdfloat(_u_speed);
dg.add_stdfloat(_v_speed);
dg.add_stdfloat(_w_speed);
dg.add_stdfloat(_r_speed);
if (manager->get_file_minor_ver() >= 33) {
dg.add_stdfloat(_w_speed);
}
if (manager->get_file_minor_ver() >= 22) {
dg.add_stdfloat(_r_speed);
}
}
/**

View File

@ -127,7 +127,7 @@ get_type_from_extension(const string &filename) const {
}
#ifdef HAVE_ZLIB
if (extension == "pz") {
if (extension == "pz" || extension == "gz") {
// If the extension is .pz, then we've got a Panda-compressed image file.
// Back up some more and get the extension before that.
size_t prev_dot = filename.rfind('.', dot - 1);

View File

@ -42,6 +42,16 @@ get_file_major_ver() const {
return _file_major;
}
/**
* Changes the minor .bam version to write. This should be called before
* init(). Each Panda version has only a fairly narrow range of versions it
* is able to write; consult the .bam documentation for more information.
*/
INLINE void BamWriter::
set_file_minor_ver(int minor_ver) {
_file_minor = minor_ver;
}
/**
* Returns the minor version number of the Bam file currently being written.
*/

View File

@ -41,8 +41,43 @@ BamWriter(DatagramSink *target) :
_next_pta_id = 1;
_long_pta_id = false;
_file_major = _bam_major_ver;
_file_minor = _bam_minor_ver;
// Check which version .bam files we should write.
if (bam_version.get_num_words() > 0) {
if (bam_version.get_num_words() != 2) {
util_cat.error()
<< "bam-version configuration variable requires two arguments.\n";
}
_file_major = bam_version[0];
_file_minor = bam_version[1];
if (_file_major < _bam_major_ver || _file_minor < 21) {
util_cat.error()
<< "bam-version is set to " << bam_version << ", but this version of "
"Panda3D cannot produce .bam files older than 6.21. Set "
"bam-version to 6 21 in Config.prc to suppress this error, or "
"leave it blank to write version " << _bam_major_ver << "."
<< _bam_minor_ver << " files.\n";
_file_major = 6;
_file_minor = 21;
bam_version.set_string_value("6 21");
} else if (_file_major > _bam_major_ver || _file_minor > _bam_minor_ver) {
util_cat.error()
<< "bam-version is set to " << bam_version << ", but this version of "
"Panda3D cannot produce .bam files newer than " << _bam_major_ver
<< "." << _bam_minor_ver << ". Set bam-version to a supported "
"version or leave it blank to write version " << _bam_major_ver
<< "." << _bam_minor_ver << " files.\n";
_file_major = _bam_major_ver;
_file_minor = _bam_minor_ver;
bam_version.set_word(0, _bam_major_ver);
bam_version.set_word(1, _bam_minor_ver);
}
} else {
_file_major = _bam_major_ver;
_file_minor = _bam_minor_ver;
}
_file_endian = bam_endian;
_file_stdfloat_double = bam_stdfloat_double;
_file_texture_mode = bam_texture_mode;
@ -98,18 +133,24 @@ init() {
_next_pta_id = 1;
_long_pta_id = false;
_file_major = _bam_major_ver;
_file_minor = _bam_minor_ver;
nassertr_always(_file_major == _bam_major_ver, false);
nassertr_always(_file_minor <= _bam_minor_ver && _file_minor >= 21, false);
_file_endian = bam_endian;
_file_texture_mode = bam_texture_mode;
// Write out the current major and minor BAM file version numbers.
Datagram header;
header.add_uint16(_bam_major_ver);
header.add_uint16(_bam_minor_ver);
header.add_uint16(_file_major);
header.add_uint16(_file_minor);
header.add_uint8(_file_endian);
header.add_bool(_file_stdfloat_double);
if (_file_major >= 6 || _file_minor >= 27) {
header.add_bool(_file_stdfloat_double);
} else {
_file_stdfloat_double = false;
}
if (!_target->put_datagram(header)) {
util_cat.error()

View File

@ -76,6 +76,7 @@ PUBLISHED:
INLINE int get_file_major_ver() const;
INLINE int get_file_minor_ver() const;
INLINE void set_file_minor_ver(int minor_ver);
INLINE BamEndian get_file_endian() const;
INLINE bool get_file_stdfloat_double() const;

View File

@ -51,6 +51,12 @@ ConfigureDef(config_util);
NotifyCategoryDef(util, "");
NotifyCategoryDef(bam, util_cat);
ConfigVariableInt bam_version
("bam-version", "",
PRC_DESC("Set this to specify which version .bam files to generate. Each "
"Panda version only supports outputting a limited number of .bam "
"versions. The default is to use the latest supported version."));
ConfigVariableEnum<BamEnums::BamEndian> bam_endian
("bam-endian", BamEnums::BE_native,
PRC_DESC("The default endianness to use for writing major numeric data "

View File

@ -33,6 +33,7 @@ NotifyCategoryDecl(bam, EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL);
// a global constant, we'll make it a member of MemoryUsage. extern
// EXPCL_PANDA_PUTIL const bool track_memory_usage;
extern EXPCL_PANDA_PUTIL ConfigVariableInt bam_version;
extern EXPCL_PANDA_PUTIL ConfigVariableEnum<BamEnums::BamEndian> bam_endian;
extern EXPCL_PANDA_PUTIL ConfigVariableBool bam_stdfloat_double;
extern EXPCL_PANDA_PUTIL ConfigVariableEnum<BamEnums::BamTextureMode> bam_texture_mode;