31 EggTextureCards() :
EggWriter(true, true) {
32 set_program_brief(
"generate an .egg file containing texture cards");
33 set_program_description
34 (
"egg-texture-cards generates an egg file consisting of several "
35 "square polygons, one for each texture name that appears on the "
38 "This is a handy thing to have for importing texture images through "
39 "egg-palettize, even when those textures do not appear on any real "
40 "geometry; it can also be used for creating a lot of simple polygons "
41 "for rendering click buttons and similar interfaces.");
44 add_runline(
"[opts] texture [texture ...] output.egg");
45 add_runline(
"[opts] -o output.egg texture [texture ...]");
46 add_runline(
"[opts] texture [texture ...] >output.egg");
49 (
"g",
"left,right,bottom,top", 0,
50 "Specifies the geometry of each polygon. The default is a unit polygon "
51 "centered on the origin: -0.5,0.5,-0.5,0.5. Polygons are always created "
52 "on the X-Y plane. If -p is not also specified, all polygons will be "
53 "the same size and shape.",
54 &EggTextureCards::dispatch_double_quad,
nullptr, &_polygon_geometry[0]);
57 (
"p",
"xpixels,ypixels", 0,
58 "Indicates that polygons should be sized in proportion to the pixel "
59 "size of the texture image. This will potentially create a "
60 "different size and shape polygon for each texture. The coordinate "
61 "pair represents the image size in "
62 "pixels that will exactly fill up the polygon described with -g (or the "
63 "default polygon if -g is not specified); smaller images will be "
64 "given proportionately smaller polygons, and larger images will be "
65 "given proportionately larger polygons.",
66 &EggTextureCards::dispatch_double_pair, &_got_pixel_scale, &_pixel_scale[0]);
69 (
"suffix",
"string", 0,
70 "Normally, each polygon is given a name based on the basename of its "
71 "corresponding texture's filename (without the filename extension). "
72 "This option specifies an ignorable suffix in the texture filename(s); "
73 "if this suffix is present, it is not included in the polygon's name. "
74 "This option may be repeated multiple times.",
75 &EggTextureCards::dispatch_vector_string,
nullptr, &_suffixes);
79 "Specifies the color of each polygon. The default is white: 1,1,1,1.",
80 &EggTextureCards::dispatch_color,
nullptr, &_polygon_color[0]);
84 "Indicates the wrap mode of the texture: \"repeat\", \"clamp\", "
85 "or any of the other modes supported by egg syntax. "
86 "The default is to leave this unspecified.",
87 &EggTextureCards::dispatch_wrap_mode,
nullptr, &_wrap_mode);
91 "Indicates the wrap mode of the texture in the U direction. This "
92 "overrides -wm, if specified.",
93 &EggTextureCards::dispatch_wrap_mode,
nullptr, &_wrap_u);
97 "Indicates the wrap mode of the texture in the V direction. This "
98 "overrides -wm, if specified.",
99 &EggTextureCards::dispatch_wrap_mode,
nullptr, &_wrap_v);
102 (
"minf",
"filter", 0,
103 "Indicates the minfilter mode of the texture: \"linear\", \"mipmap\", "
104 "or any of the other modes supported by egg syntax. "
105 "The default is to leave this unspecified.",
106 &EggTextureCards::dispatch_filter_type,
nullptr, &_minfilter);
109 (
"magf",
"filter", 0,
110 "Indicates the magfilter mode of the texture: \"linear\" or \"nearest\". "
111 "The default is to leave this unspecified.",
112 &EggTextureCards::dispatch_filter_type,
nullptr, &_magfilter);
115 (
"aniso",
"degree", 0,
116 "Indicates the anisotropic degree of the texture. "
117 "The default is to leave this unspecified.",
118 &EggTextureCards::dispatch_int, &_got_aniso_degree, &_aniso_degree);
121 (
"ql",
"[default | fastest | normal | best]", 0,
122 "Specifies the quality level of the texture. This mainly affects "
123 "the tinydisplay software renderer.",
124 &EggTextureCards::dispatch_quality_level,
nullptr, &_quality_level);
128 "Indicates the format for all textures: typical choices are \"rgba12\" "
129 "or \"rgb5\" or \"alpha\". The default is to leave this unspecified.",
130 &EggTextureCards::dispatch_format,
nullptr, &_format);
134 "Indicates the format for one-channel textures only. If specified, this "
135 "overrides the format specified by -f.",
136 &EggTextureCards::dispatch_format,
nullptr, &_format_1);
140 "Indicates the format for two-channel textures only. If specified, this "
141 "overrides the format specified by -f.",
142 &EggTextureCards::dispatch_format,
nullptr, &_format_2);
146 "Indicates the format for three-channel textures only. If specified, this "
147 "overrides the format specified by -f.",
148 &EggTextureCards::dispatch_format,
nullptr, &_format_3);
152 "Indicates the format for four-channel textures only. If specified, this "
153 "overrides the format specified by -f.",
154 &EggTextureCards::dispatch_format,
nullptr, &_format_4);
158 "Make the textured polygons backfaced (two-sided).",
159 &EggTextureCards::dispatch_none, &_apply_bface);
162 (
"fps",
"frame-rate", 0,
163 "Normally, all of the texture cards are created as a series of nodes "
164 "beneath a SequenceNode. This allows all of the cards to be viewed, "
165 "one at a time, if the output file is loaded in pview. It also has the "
166 "nice side-effect of creating an automatic texture flip that can be "
167 "used directly by applications; use this parameter to specify the "
168 "frame rate of that texture flip.",
169 &EggTextureCards::dispatch_double,
nullptr, &_frame_rate);
173 "Don't treat it as an error if the input file references pathnames "
174 "(e.g. textures) that don't exist. Normally, this will be flagged as "
175 "an error and the command aborted; with this option, an egg file will "
176 "be generated anyway, referencing pathnames that do not exist.",
177 &EggTextureCards::dispatch_none, &_noexist);
179 _polygon_geometry.set(-0.5, 0.5, -0.5, 0.5);
180 _polygon_color.set(1.0, 1.0, 1.0, 1.0);
181 _wrap_mode = EggTexture::WM_unspecified;
182 _wrap_u = EggTexture::WM_unspecified;
183 _wrap_v = EggTexture::WM_unspecified;
184 _minfilter = EggTexture::FT_unspecified;
185 _magfilter = EggTexture::FT_unspecified;
187 _quality_level = EggTexture::QL_unspecified;
188 _format = EggTexture::F_unspecified;
189 _format_1 = EggTexture::F_unspecified;
190 _format_2 = EggTexture::F_unspecified;
191 _format_3 = EggTexture::F_unspecified;
192 _format_4 = EggTexture::F_unspecified;
201 bool EggTextureCards::
203 if (!check_last_arg(args, 0)) {
208 nout <<
"No texture names specified on the command line.\n";
212 ProgramBase::Args::iterator ai;
213 for (ai = args.begin(); ai != args.end(); ++ai) {
225 bool EggTextureCards::
226 dispatch_wrap_mode(
const string &opt,
const string &arg,
void *var) {
227 EggTexture::WrapMode *wmp = (EggTexture::WrapMode *)var;
230 if (*wmp == EggTexture::WM_unspecified) {
233 *wmp = EggTexture::WM_repeat;
234 }
else if (arg ==
"c") {
235 *wmp = EggTexture::WM_clamp;
237 nout <<
"Invalid wrap mode parameter for -" << opt <<
": "
251 bool EggTextureCards::
252 dispatch_filter_type(
const string &opt,
const string &arg,
void *var) {
253 EggTexture::FilterType *ftp = (EggTexture::FilterType *)var;
256 if (*ftp == EggTexture::FT_unspecified) {
258 nout <<
"Invalid filter type parameter for -" << opt <<
": "
271 bool EggTextureCards::
272 dispatch_quality_level(
const string &opt,
const string &arg,
void *var) {
273 EggTexture::QualityLevel *qlp = (EggTexture::QualityLevel *)var;
276 if (*qlp == EggTexture::QL_unspecified) {
277 nout <<
"Invalid quality level parameter for -" << opt <<
": "
290 bool EggTextureCards::
291 dispatch_format(
const string &opt,
const string &arg,
void *var) {
292 EggTexture::Format *fp = (EggTexture::Format *)var;
295 if (*fp == EggTexture::F_unspecified) {
296 nout <<
"Invalid format parameter for -" << opt <<
": "
312 bool EggTextureCards::
313 scan_texture(
const Filename &filename, LVecBase4d &geometry,
317 nout <<
"Unable to read image " << filename <<
"\n";
323 double xscale = header.
get_x_size() / _pixel_scale[0];
324 double yscale = header.
get_y_size() / _pixel_scale[1];
326 geometry.set(_polygon_geometry[0] * xscale,
327 _polygon_geometry[1] * xscale,
328 _polygon_geometry[2] * yscale,
329 _polygon_geometry[3] * yscale);
337 void EggTextureCards::
338 make_vertices(
const LPoint4d &geometry,
EggVertexPool *vpool,
343 (LPoint3d(geometry[0], geometry[3], 0.0));
345 (LPoint3d(geometry[0], geometry[2], 0.0));
347 (LPoint3d(geometry[1], geometry[2], 0.0));
349 (LPoint3d(geometry[1], geometry[3], 0.0));
351 v1->
set_uv(LTexCoordd(0.0, 1.0));
352 v2->
set_uv(LTexCoordd(0.0, 0.0));
353 v3->
set_uv(LTexCoordd(1.0, 0.0));
354 v4->
set_uv(LTexCoordd(1.0, 1.0));
360 void EggTextureCards::
367 _data->add_child(group);
372 if (_texture_names.size() > 1) {
373 group->set_switch_flag(
true);
374 group->set_switch_fps(_frame_rate);
382 if (!_got_pixel_scale) {
385 make_vertices(_polygon_geometry, vpool, v1, v2, v3, v4);
390 vector_string::const_iterator ti;
391 for (ti = _texture_names.begin(); ti != _texture_names.end(); ++ti) {
396 vector_string::const_iterator si;
397 for (si = _suffixes.begin(); si != _suffixes.end(); ++si) {
398 const string &suffix = (*si);
399 int prefix = (int)name.length() - (int)suffix.length();
400 if (prefix > 0 && name.substr(prefix) == suffix) {
401 name = name.substr(0, prefix);
408 bool texture_ok = scan_texture(filename, geometry, num_channels);
413 if (_got_pixel_scale) {
415 make_vertices(geometry, vpool, v1, v2, v3, v4);
417 make_vertices(_polygon_geometry, vpool, v1, v2, v3, v4);
422 tref->set_wrap_mode(_wrap_mode);
423 tref->set_wrap_u(_wrap_u);
424 tref->set_wrap_v(_wrap_v);
425 tref->set_minfilter(_minfilter);
426 tref->set_magfilter(_magfilter);
427 if (_got_aniso_degree) {
430 tref->set_quality_level(_quality_level);
433 switch (num_channels) {
435 tref->set_format(_format_1);
439 tref->set_format(_format_2);
443 tref->set_format(_format_3);
447 tref->set_format(_format_4);
452 if (tref->get_format() == EggTexture::F_unspecified) {
453 tref->set_format(_format);
465 poly->set_color(_polygon_color);
477 if (all_ok || _noexist) {
480 nout <<
"Some textures not found; not generating egg file.\n";
486 int main(
int argc,
char *argv[]) {