00001 // Filename: sourceTextureImage.cxx 00002 // Created by: drose (29Nov00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "sourceTextureImage.h" 00016 #include "textureImage.h" 00017 #include "filenameUnifier.h" 00018 00019 #include "pnmImageHeader.h" 00020 #include "datagram.h" 00021 #include "datagramIterator.h" 00022 #include "bamReader.h" 00023 #include "bamWriter.h" 00024 00025 TypeHandle SourceTextureImage::_type_handle; 00026 00027 //////////////////////////////////////////////////////////////////// 00028 // Function: SourceTextureImage::Default Constructor 00029 // Access: Private 00030 // Description: The default constructor is only for the convenience 00031 // of the Bam reader. 00032 //////////////////////////////////////////////////////////////////// 00033 SourceTextureImage:: 00034 SourceTextureImage() { 00035 _texture = (TextureImage *)NULL; 00036 00037 _egg_count = 0; 00038 _read_header = false; 00039 _successfully_read_header = false; 00040 } 00041 00042 //////////////////////////////////////////////////////////////////// 00043 // Function: SourceTextureImage::Constructor 00044 // Access: Public 00045 // Description: 00046 //////////////////////////////////////////////////////////////////// 00047 SourceTextureImage:: 00048 SourceTextureImage(TextureImage *texture, const Filename &filename, 00049 const Filename &alpha_filename, int alpha_file_channel) : 00050 _texture(texture) 00051 { 00052 _filename = filename; 00053 _alpha_filename = alpha_filename; 00054 _alpha_file_channel = alpha_file_channel; 00055 _egg_count = 0; 00056 _read_header = false; 00057 _successfully_read_header = false; 00058 } 00059 00060 //////////////////////////////////////////////////////////////////// 00061 // Function: SourceTextureImage::get_texture 00062 // Access: Public 00063 // Description: Returns the particular texture that this image is one 00064 // of the sources for. 00065 //////////////////////////////////////////////////////////////////// 00066 TextureImage *SourceTextureImage:: 00067 get_texture() const { 00068 return _texture; 00069 } 00070 00071 //////////////////////////////////////////////////////////////////// 00072 // Function: SourceTextureImage::increment_egg_count 00073 // Access: Public 00074 // Description: Increments by one the number of egg files that are 00075 // known to reference this SourceTextureImage. 00076 //////////////////////////////////////////////////////////////////// 00077 void SourceTextureImage:: 00078 increment_egg_count() { 00079 _egg_count++; 00080 } 00081 00082 //////////////////////////////////////////////////////////////////// 00083 // Function: SourceTextureImage::get_egg_count 00084 // Access: Public 00085 // Description: Returns the number of egg files that share this 00086 // SourceTextureImage. 00087 //////////////////////////////////////////////////////////////////// 00088 int SourceTextureImage:: 00089 get_egg_count() const { 00090 return _egg_count; 00091 } 00092 00093 //////////////////////////////////////////////////////////////////// 00094 // Function: SourceTextureImage::get_size 00095 // Access: Public 00096 // Description: Determines the size of the SourceTextureImage, if it 00097 // is not already known. Returns true if the size was 00098 // successfully determined (or if was already known), or 00099 // false if the size could not be determined (for 00100 // instance, because the image file is missing). After 00101 // this call returns true, get_x_size() etc. may be 00102 // safely called to return the size. 00103 //////////////////////////////////////////////////////////////////// 00104 bool SourceTextureImage:: 00105 get_size() { 00106 if (!_size_known) { 00107 return read_header(); 00108 } 00109 return true; 00110 } 00111 00112 //////////////////////////////////////////////////////////////////// 00113 // Function: SourceTextureImage::read_header 00114 // Access: Public 00115 // Description: Reads the actual image header to determine the image 00116 // properties, like its size. Returns true if the image 00117 // header is successfully read (or if has previously 00118 // been successfully read this session), false 00119 // otherwise. After this call returns true, 00120 // get_x_size() etc. may be safely called to return the 00121 // newly determined size. 00122 //////////////////////////////////////////////////////////////////// 00123 bool SourceTextureImage:: 00124 read_header() { 00125 if (_read_header) { 00126 return _successfully_read_header; 00127 } 00128 00129 _read_header = true; 00130 _successfully_read_header = false; 00131 00132 PNMImageHeader header; 00133 if (!header.read_header(_filename)) { 00134 nout << "Warning: cannot read texture " 00135 << FilenameUnifier::make_user_filename(_filename) << "\n"; 00136 return false; 00137 } 00138 00139 set_header(header); 00140 00141 return true; 00142 } 00143 00144 //////////////////////////////////////////////////////////////////// 00145 // Function: SourceTextureImage::set_header 00146 // Access: Public 00147 // Description: Sets the header information associated with this 00148 // image, as if it were loaded from the disk. 00149 //////////////////////////////////////////////////////////////////// 00150 void SourceTextureImage:: 00151 set_header(const PNMImageHeader &header) { 00152 _x_size = header.get_x_size(); 00153 _y_size = header.get_y_size(); 00154 int num_channels = header.get_num_channels(); 00155 00156 if (!_alpha_filename.empty() && _alpha_filename.exists()) { 00157 // Assume if we have an alpha filename, that we have an additional 00158 // alpha channel. 00159 if (num_channels == 1 || num_channels == 3) { 00160 num_channels++; 00161 } 00162 } 00163 _properties.set_num_channels(num_channels); 00164 00165 _size_known = true; 00166 _successfully_read_header = true; 00167 } 00168 00169 00170 //////////////////////////////////////////////////////////////////// 00171 // Function: SourceTextureImage::register_with_read_factory 00172 // Access: Public, Static 00173 // Description: Registers the current object as something that can be 00174 // read from a Bam file. 00175 //////////////////////////////////////////////////////////////////// 00176 void SourceTextureImage:: 00177 register_with_read_factory() { 00178 BamReader::get_factory()-> 00179 register_factory(get_class_type(), make_SourceTextureImage); 00180 } 00181 00182 //////////////////////////////////////////////////////////////////// 00183 // Function: SourceTextureImage::write_datagram 00184 // Access: Public, Virtual 00185 // Description: Fills the indicated datagram up with a binary 00186 // representation of the current object, in preparation 00187 // for writing to a Bam file. 00188 //////////////////////////////////////////////////////////////////// 00189 void SourceTextureImage:: 00190 write_datagram(BamWriter *writer, Datagram &datagram) { 00191 ImageFile::write_datagram(writer, datagram); 00192 writer->write_pointer(datagram, _texture); 00193 00194 // We don't store _egg_count; instead, we count these up again each 00195 // session. 00196 00197 // We don't store _read_header or _successfully_read_header in the 00198 // Bam file; these are transitory and we need to reread the image 00199 // header for each session (in case the image files change between 00200 // sessions). 00201 } 00202 00203 //////////////////////////////////////////////////////////////////// 00204 // Function: SourceTextureImage::complete_pointers 00205 // Access: Public, Virtual 00206 // Description: Called after the object is otherwise completely read 00207 // from a Bam file, this function's job is to store the 00208 // pointers that were retrieved from the Bam file for 00209 // each pointer object written. The return value is the 00210 // number of pointers processed from the list. 00211 //////////////////////////////////////////////////////////////////// 00212 int SourceTextureImage:: 00213 complete_pointers(TypedWritable **p_list, BamReader *manager) { 00214 int pi = ImageFile::complete_pointers(p_list, manager); 00215 00216 DCAST_INTO_R(_texture, p_list[pi++], pi); 00217 return pi; 00218 } 00219 00220 //////////////////////////////////////////////////////////////////// 00221 // Function: SourceTextureImage::make_SourceTextureImage 00222 // Access: Protected 00223 // Description: This method is called by the BamReader when an object 00224 // of this type is encountered in a Bam file; it should 00225 // allocate and return a new object with all the data 00226 // read. 00227 //////////////////////////////////////////////////////////////////// 00228 TypedWritable *SourceTextureImage:: 00229 make_SourceTextureImage(const FactoryParams ¶ms) { 00230 SourceTextureImage *me = new SourceTextureImage; 00231 DatagramIterator scan; 00232 BamReader *manager; 00233 00234 parse_params(params, scan, manager); 00235 me->fillin(scan, manager); 00236 return me; 00237 } 00238 00239 //////////////////////////////////////////////////////////////////// 00240 // Function: SourceTextureImage::fillin 00241 // Access: Protected 00242 // Description: Reads the binary data from the given datagram 00243 // iterator, which was written by a previous call to 00244 // write_datagram(). 00245 //////////////////////////////////////////////////////////////////// 00246 void SourceTextureImage:: 00247 fillin(DatagramIterator &scan, BamReader *manager) { 00248 ImageFile::fillin(scan, manager); 00249 manager->read_pointer(scan); // _texture 00250 }