Panda3D
Loading...
Searching...
No Matches
fltTexture.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file fltTexture.cxx
10 * @author drose
11 * @date 2000-08-25
12 */
13
14#include "fltTexture.h"
15#include "fltRecordReader.h"
16#include "fltRecordWriter.h"
17#include "fltHeader.h"
18#include "pathReplace.h"
19#include "config_putil.h"
20
21TypeHandle FltTexture::_type_handle;
22
23/**
24 *
25 */
26FltTexture::
27FltTexture(FltHeader *header) : FltRecord(header) {
28 _pattern_index = -1;
29 _x_location = 0;
30 _y_location = 0;
31
32 _num_texels_u = 0;
33 _num_texels_v = 0;
34 _real_world_size_u = 0;
35 _real_world_size_v = 0;
36 _up_vector_x = 0;
37 _up_vector_y = 1;
38 _file_format = FF_none;
39 _min_filter = MN_point;
40 _mag_filter = MG_point;
41 _repeat = RT_repeat;
42 _repeat_u = RT_repeat;
43 _repeat_v = RT_repeat;
44 _modify_flag = 0;
45 _x_pivot_point = 0;
46 _y_pivot_point = 0;
47 _env_type = ET_modulate;
48 _intensity_is_alpha = false;
49 _float_real_world_size_u = 0.0;
50 _float_real_world_size_v = 0.0;
51 _imported_origin_code = 0;
52 _kernel_version = 1520;
53 _internal_format = IF_default;
54 _external_format = EF_default;
55 _use_mipmap_kernel = false;
56 memset(_mipmap_kernel, 0, sizeof(_mipmap_kernel));
57 _use_lod_scale = false;
58 memset(_lod_scale, 0, sizeof(_lod_scale));
59 _clamp = 0.0;
60 _mag_filter_alpha = MG_point;
61 _mag_filter_color = MG_point;
62 _lambert_conic_central_meridian = 0.0;
63 _lambert_conic_upper_latitude = 0.0;
64 _lambert_conic_lower_latitude = 0.0;
65 _use_detail = false;
66 _detail_j = 0;
67 _detail_k = 0;
68 _detail_m = 0;
69 _detail_n = 0;
70 _detail_scramble = 0;
71 _use_tile = false;
72 _tile_lower_left_u = 0.0;
73 _tile_lower_left_v = 0.0;
74 _tile_upper_right_u = 0.0;
75 _tile_upper_right_v = 0.0;
76 _projection = PT_flat_earth;
77 _earth_model = EM_wgs84;
78 _utm_zone = 0;
79 _image_origin = IO_lower_left;
80 _geospecific_points_units = PU_degrees;
81 _geospecific_hemisphere = H_southern;
82 _file_version = 1501;
83}
84
85/**
86 * Walks the hierarchy at this record and below and copies the
87 * _converted_filename record into the _orig_filename record, so the flt file
88 * will be written out with the converted filename instead of what was
89 * originally read in.
90 */
93 _orig_filename = _converted_filename.to_os_generic();
95}
96
97/**
98 * Returns the name of the texture image file.
99 */
101get_texture_filename() const {
102 return _converted_filename;
103}
104
105/**
106 * Changes the name of the texture image file.
107 */
109set_texture_filename(const Filename &filename) {
110 _converted_filename = filename;
111 _orig_filename = _converted_filename.to_os_generic();
112}
113
114/**
115 * Returns the name of the texture's associated .attr file. This contains
116 * some additional MultiGen information about the texture parameters. This
117 * is, of course, just the name of the texture with .attr appended.
118 *
119 * Normally, it won't be necessary to access this file directly; you can call
120 * read_attr_data() or write_attr_data() to get at the data stored in this
121 * file. (And read_attr_data() is called automatically when the Flt file is
122 * read in.)
123 */
125get_attr_filename() const {
126 std::string texture_filename = get_texture_filename();
127 return Filename::binary_filename(texture_filename + ".attr");
128}
129
130/**
131 * Opens up the texture's .attr file and reads its data into the extra
132 * FltTexture fields. This is normally performed automatically when the Flt
133 * file is read from disk.
134 */
137 Filename attr_filename = get_attr_filename();
138
139 std::ifstream attr;
140 if (!attr_filename.open_read(attr)) {
141 return FE_could_not_open;
142 }
143
144 // Determine the file's size so we can read it all into one big datagram.
145 attr.seekg(0, std::ios::end);
146 if (attr.fail()) {
147 return FE_read_error;
148 }
149 std::streampos length = attr.tellg();
150
151 char *buffer = new char[length];
152
153 attr.seekg(0, std::ios::beg);
154 attr.read(buffer, length);
155 if (attr.fail()) {
156 return FE_read_error;
157 }
158
159 Datagram datagram(buffer, length);
160 delete[] buffer;
161
162 return unpack_attr(datagram);
163}
164
165/**
166 * Writes the texture's .attr file. This may or may not be performed
167 * automatically, according to the setting of
168 * FltHeader::set_auto_attr_update().
169 */
171write_attr_data() const {
173}
174
175/**
176 * Writes the texture's .attr file to the named file.
177 */
179write_attr_data(Filename attr_filename) const {
180 Datagram datagram;
181 FltError result = pack_attr(datagram);
182 if (result != FE_ok) {
183 return result;
184 }
185
186 attr_filename.set_binary();
187 std::ofstream attr;
188 if (!attr_filename.open_write(attr)) {
189 return FE_could_not_open;
190 }
191
192 attr.write((const char *)datagram.get_data(), datagram.get_length());
193 if (attr.fail()) {
194 return FE_write_error;
195 }
196 return FE_ok;
197}
198
199/**
200 * Fills in the information in this record based on the information given in
201 * the indicated datagram, whose opcode has already been read. Returns true
202 * on success, false if the datagram is invalid.
203 */
204bool FltTexture::
205extract_record(FltRecordReader &reader) {
206 if (!FltRecord::extract_record(reader)) {
207 return false;
208 }
209
210 nassertr(reader.get_opcode() == FO_texture, false);
211 DatagramIterator &iterator = reader.get_iterator();
212
213 if (_header->get_flt_version() < 1420) {
214 _orig_filename = iterator.get_fixed_string(80);
215 } else {
216 _orig_filename = iterator.get_fixed_string(200);
217 }
218 _converted_filename = _header->convert_path(Filename::from_os_specific(_orig_filename), get_model_path());
219 _pattern_index = iterator.get_be_int32();
220 _x_location = iterator.get_be_int32();
221 _y_location = iterator.get_be_int32();
222
223 if (read_attr_data() != FE_ok) {
224 nout << "Unable to read attribute file " << get_attr_filename() << "\n";
225 }
226
227 check_remaining_size(iterator);
228 return true;
229}
230
231/**
232 * Fills up the current record on the FltRecordWriter with data for this
233 * record, but does not advance the writer. Returns true on success, false if
234 * there is some error.
235 */
236bool FltTexture::
237build_record(FltRecordWriter &writer) const {
238 if (!FltRecord::build_record(writer)) {
239 return false;
240 }
241
242 writer.set_opcode(FO_texture);
243 Datagram &datagram = writer.update_datagram();
244
245 datagram.add_fixed_string(_orig_filename, 200);
246 datagram.add_be_int32(_pattern_index);
247 datagram.add_be_int32(_x_location);
248 datagram.add_be_int32(_y_location);
249
250 if (_header->get_auto_attr_update() == FltHeader::AU_always ||
251 (_header->get_auto_attr_update() == FltHeader::AU_if_missing &&
252 !get_attr_filename().exists())) {
253 if (write_attr_data() != FE_ok) {
254 nout << "Unable to write attribute file " << get_attr_filename() << "\n";
255 }
256 }
257
258 return true;
259}
260
261/**
262 * Reads the data from the attribute file.
263 */
264FltError FltTexture::
265unpack_attr(const Datagram &datagram) {
266 DatagramIterator iterator(datagram);
267
268 _num_texels_u = iterator.get_be_int32();
269 _num_texels_v = iterator.get_be_int32();
270 _real_world_size_u = iterator.get_be_int32();
271 _real_world_size_v = iterator.get_be_int32();
272 _up_vector_x = iterator.get_be_int32();
273 _up_vector_y = iterator.get_be_int32();
274 _file_format = (FileFormat)iterator.get_be_int32();
275 _min_filter = (Minification)iterator.get_be_int32();
276 _mag_filter = (Magnification)iterator.get_be_int32();
277 _repeat = (RepeatType)iterator.get_be_int32();
278 _repeat_u = (RepeatType)iterator.get_be_int32();
279 _repeat_v = (RepeatType)iterator.get_be_int32();
280 _modify_flag = iterator.get_be_int32();
281 _x_pivot_point = iterator.get_be_int32();
282 _y_pivot_point = iterator.get_be_int32();
283 _env_type = (EnvironmentType)iterator.get_be_int32();
284 _intensity_is_alpha = (iterator.get_be_int32() != 0);
285 iterator.skip_bytes(4 * 8);
286 iterator.skip_bytes(4); // Undocumented padding.
287 _float_real_world_size_u = iterator.get_be_float64();
288 _float_real_world_size_v = iterator.get_be_float64();
289 _imported_origin_code = iterator.get_be_int32();
290 _kernel_version = iterator.get_be_int32();
291 _internal_format = (InternalFormat)iterator.get_be_int32();
292 _external_format = (ExternalFormat)iterator.get_be_int32();
293 _use_mipmap_kernel = (iterator.get_be_int32() != 0);
294 int i;
295 for (i = 0; i < 8; i++) {
296 _mipmap_kernel[i] = iterator.get_be_float32();
297 }
298 _use_lod_scale = (iterator.get_be_int32() != 0);
299 for (i = 0; i < 8; i++) {
300 _lod_scale[i]._lod = iterator.get_be_float32();
301 _lod_scale[i]._scale = iterator.get_be_float32();
302 }
303 _clamp = iterator.get_be_float32();
304 _mag_filter_alpha = (Magnification)iterator.get_be_int32();
305 _mag_filter_color = (Magnification)iterator.get_be_int32();
306 iterator.skip_bytes(4 + 4 * 8);
307 _lambert_conic_central_meridian = iterator.get_be_float64();
308 _lambert_conic_upper_latitude = iterator.get_be_float64();
309 _lambert_conic_lower_latitude = iterator.get_be_float64();
310 iterator.skip_bytes(8 + 4 * 5);
311 _use_detail = (iterator.get_be_int32() != 0);
312 _detail_j = iterator.get_be_int32();
313 _detail_k = iterator.get_be_int32();
314 _detail_m = iterator.get_be_int32();
315 _detail_n = iterator.get_be_int32();
316 _detail_scramble = iterator.get_be_int32();
317 _use_tile = (iterator.get_be_int32() != 0);
318 _tile_lower_left_u = iterator.get_be_float32();
319 _tile_lower_left_v = iterator.get_be_float32();
320 _tile_upper_right_u = iterator.get_be_float32();
321 _tile_upper_right_v = iterator.get_be_float32();
322 _projection = (ProjectionType)iterator.get_be_int32();
323 _earth_model = (EarthModel)iterator.get_be_int32();
324 iterator.skip_bytes(4);
325 _utm_zone = iterator.get_be_int32();
326 _image_origin = (ImageOrigin)iterator.get_be_int32();
327 _geospecific_points_units = (PointsUnits)iterator.get_be_int32();
328 _geospecific_hemisphere = (Hemisphere)iterator.get_be_int32();
329 iterator.skip_bytes(4 + 4 + 149 * 4);
330 iterator.skip_bytes(8); // Undocumented padding.
331 _comment = iterator.get_fixed_string(512);
332
333 if (iterator.get_remaining_size() != 0) {
334 iterator.skip_bytes(13 * 4);
335 iterator.skip_bytes(4); // Undocumented padding.
336 _file_version = iterator.get_be_int32();
337
338 // Now read the geospecific control points.
339 _geospecific_control_points.clear();
340 int num_points = iterator.get_be_int32();
341 if (num_points > 0) {
342 iterator.skip_bytes(4);
343
344 while (num_points > 0) {
345 GeospecificControlPoint gcp;
346 gcp._uv[0] = iterator.get_be_float64();
347 gcp._uv[1] = iterator.get_be_float64();
348 gcp._real_earth[0] = iterator.get_be_float64();
349 gcp._real_earth[1] = iterator.get_be_float64();
350 }
351 }
352
353 if (iterator.get_remaining_size() != 0) {
354 int num_defs = iterator.get_be_int32();
355 while (num_defs > 0) {
356 SubtextureDef def;
357 def._name = iterator.get_fixed_string(32);
358 def._left = iterator.get_be_int32();
359 def._bottom = iterator.get_be_int32();
360 def._right = iterator.get_be_int32();
361 def._top = iterator.get_be_int32();
362 }
363 }
364 }
365
366 check_remaining_size(iterator);
367 return FE_ok;
368}
369
370/**
371 * Packs the attribute data into a big datagram.
372 */
373FltError FltTexture::
374pack_attr(Datagram &datagram) const {
375 datagram.add_be_int32(_num_texels_u);
376 datagram.add_be_int32(_num_texels_v);
377 datagram.add_be_int32(_real_world_size_u);
378 datagram.add_be_int32(_real_world_size_v);
379 datagram.add_be_int32(_up_vector_x);
380 datagram.add_be_int32(_up_vector_y);
381 datagram.add_be_int32(_file_format);
382 datagram.add_be_int32(_min_filter);
383 datagram.add_be_int32(_mag_filter);
384 datagram.add_be_int32(_repeat);
385 datagram.add_be_int32(_repeat_u);
386 datagram.add_be_int32(_repeat_v);
387 datagram.add_be_int32(_modify_flag);
388 datagram.add_be_int32(_x_pivot_point);
389 datagram.add_be_int32(_y_pivot_point);
390 datagram.add_be_int32(_env_type);
391 datagram.add_be_int32(_intensity_is_alpha);
392 datagram.pad_bytes(4 * 8);
393 datagram.pad_bytes(4); // Undocumented padding.
394 datagram.add_be_float64(_float_real_world_size_u);
395 datagram.add_be_float64(_float_real_world_size_v);
396 datagram.add_be_int32(_imported_origin_code);
397 datagram.add_be_int32(_kernel_version);
398 datagram.add_be_int32(_internal_format);
399 datagram.add_be_int32(_external_format);
400 datagram.add_be_int32(_use_mipmap_kernel);
401 int i;
402 for (i = 0; i < 8; i++) {
403 datagram.add_be_float32(_mipmap_kernel[i]);
404 }
405 datagram.add_be_int32(_use_lod_scale);
406 for (i = 0; i < 8; i++) {
407 datagram.add_be_float32(_lod_scale[i]._lod);
408 datagram.add_be_float32(_lod_scale[i]._scale);
409 }
410 datagram.add_be_float32(_clamp);
411 datagram.add_be_int32(_mag_filter_alpha);
412 datagram.add_be_int32(_mag_filter_color);
413 datagram.pad_bytes(4 + 4 * 8);
414 datagram.add_be_float64(_lambert_conic_central_meridian);
415 datagram.add_be_float64(_lambert_conic_upper_latitude);
416 datagram.add_be_float64(_lambert_conic_lower_latitude);
417 datagram.pad_bytes(8 + 4 * 5);
418 datagram.add_be_int32(_use_detail);
419 datagram.add_be_int32(_detail_j);
420 datagram.add_be_int32(_detail_k);
421 datagram.add_be_int32(_detail_m);
422 datagram.add_be_int32(_detail_n);
423 datagram.add_be_int32(_detail_scramble);
424 datagram.add_be_int32(_use_tile);
425 datagram.add_be_float32(_tile_lower_left_u);
426 datagram.add_be_float32(_tile_lower_left_v);
427 datagram.add_be_float32(_tile_upper_right_u);
428 datagram.add_be_float32(_tile_upper_right_v);
429 datagram.add_be_int32(_projection);
430 datagram.add_be_int32(_earth_model);
431 datagram.pad_bytes(4);
432 datagram.add_be_int32(_utm_zone);
433 datagram.add_be_int32(_image_origin);
434 datagram.add_be_int32(_geospecific_points_units);
435 datagram.add_be_int32(_geospecific_hemisphere);
436 datagram.pad_bytes(4 + 4 + 149 * 4);
437 datagram.pad_bytes(8); // Undocumented padding.
438 datagram.add_fixed_string(_comment, 512);
439 datagram.pad_bytes(13 * 4);
440 datagram.pad_bytes(4); // Undocumented padding.
441 datagram.add_be_int32(_file_version);
442
443 // Now write the geospecific control points.
444 datagram.add_be_int32(_geospecific_control_points.size());
445 if (!_geospecific_control_points.empty()) {
446 datagram.pad_bytes(4);
447 GeospecificControlPoints::const_iterator pi;
448 for (pi = _geospecific_control_points.begin();
449 pi != _geospecific_control_points.end();
450 ++pi) {
451 const GeospecificControlPoint &gcp = (*pi);
452 datagram.add_be_float64(gcp._uv[0]);
453 datagram.add_be_float64(gcp._uv[1]);
454 datagram.add_be_float64(gcp._real_earth[0]);
455 datagram.add_be_float64(gcp._real_earth[1]);
456 }
457 }
458
459 // Also write out the subtexture definitions.
460 datagram.add_be_int32(_subtexture_defs.size());
461 SubtextureDefs::const_iterator di;
462 for (di = _subtexture_defs.begin();
463 di != _subtexture_defs.end();
464 ++di) {
465 const SubtextureDef &def = (*di);
466 datagram.add_fixed_string(def._name, 31);
467 datagram.add_int8(0);
468 datagram.add_be_int32(def._left);
469 datagram.add_be_int32(def._bottom);
470 datagram.add_be_int32(def._right);
471 datagram.add_be_int32(def._top);
472 }
473
474 return FE_ok;
475}
A class to retrieve the individual data elements previously stored in a Datagram.
void skip_bytes(size_t size)
Skips over the indicated number of bytes in the datagram.
int32_t get_be_int32()
Extracts a signed 32-bit big-endian integer.
PN_float32 get_be_float32()
Extracts a 32-bit big-endian single-precision floating-point number.
std::string get_fixed_string(size_t size)
Extracts a fixed-length string.
PN_float64 get_be_float64()
Extracts a 64-bit big-endian floating-point number.
size_t get_remaining_size() const
Return the bytes left in the datagram.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition datagram.h:38
size_t get_length() const
Returns the number of bytes in the datagram.
Definition datagram.I:335
void add_be_int32(int32_t value)
Adds a signed 32-bit big-endian integer to the datagram.
Definition datagram.I:154
void add_be_float32(PN_float32 value)
Adds a 32-bit single-precision big-endian floating-point number to the datagram.
Definition datagram.I:200
void add_fixed_string(const std::string &str, size_t size)
Adds a fixed-length string to the datagram.
Definition datagram.I:263
void add_be_float64(PN_float64 value)
Adds a 64-bit big-endian floating-point number to the datagram.
Definition datagram.I:209
void pad_bytes(size_t size)
Adds the indicated number of zero bytes to the datagram.
Definition datagram.cxx:99
const void * get_data() const
Returns a pointer to the beginning of the datagram's data.
Definition datagram.I:327
void add_int8(int8_t value)
Adds a signed 8-bit integer to the datagram.
Definition datagram.I:42
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
void set_binary()
Indicates that the filename represents a binary file.
Definition filename.I:414
std::string to_os_generic() const
This is similar to to_os_specific(), but it is designed to generate a filename that can be understood...
bool open_write(std::ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
This is the first bead in the file, the top of the bead hierarchy, and the primary interface to readi...
Definition fltHeader.h:44
This class turns an istream into a sequence of FltRecords by reading a sequence of Datagrams and extr...
FltOpcode get_opcode() const
Returns the opcode associated with the current record.
DatagramIterator & get_iterator()
Returns an iterator suitable for extracting data from the current record.
This class writes a sequence of FltRecords to an ostream, handling opcode and size counts properly.
void set_opcode(FltOpcode opcode)
Sets the opcode associated with the current record.
Datagram & update_datagram()
Returns a modifiable reference to the datagram associated with the current record.
The base class for all kinds of records in a MultiGen OpenFlight file.
Definition fltRecord.h:36
void check_remaining_size(const DatagramIterator &di, const std::string &name=std::string()) const
Checks that the iterator has no bytes left, as it should at the end of a successfully read record.
virtual void apply_converted_filenames()
Walks the hierarchy at this record and below and copies the _converted_filename record into the _orig...
FltError write_attr_data() const
Writes the texture's .attr file.
Filename get_attr_filename() const
Returns the name of the texture's associated .attr file.
FltError read_attr_data()
Opens up the texture's .attr file and reads its data into the extra FltTexture fields.
void set_texture_filename(const Filename &filename)
Changes the name of the texture image file.
Filename get_texture_filename() const
Returns the name of the texture image file.
virtual void apply_converted_filenames()
Walks the hierarchy at this record and below and copies the _converted_filename record into the _orig...
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.