eggTextureCards.cxx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. // Filename: eggTextureCards.cxx
  2. // Created by: drose (21Feb01)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://www.panda3d.org/license.txt .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. #include "eggTextureCards.h"
  19. #include <eggGroup.h>
  20. #include <eggVertexPool.h>
  21. #include <eggVertex.h>
  22. #include <eggTexture.h>
  23. #include <eggPolygon.h>
  24. #include <pnmImageHeader.h>
  25. #include <algorithm>
  26. ////////////////////////////////////////////////////////////////////
  27. // Function: EggTextureCards::Constructor
  28. // Access: Public
  29. // Description:
  30. ////////////////////////////////////////////////////////////////////
  31. EggTextureCards::
  32. EggTextureCards() : EggWriter(true, true) {
  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 "
  36. "command line.\n\n"
  37. "This is a handy thing to have for importing texture images through "
  38. "egg-palettize, even when those textures do not appear on any real "
  39. "geometry; it can also be used for creating a lot of simple polygons "
  40. "for rendering click buttons and similar interfaces.");
  41. clear_runlines();
  42. add_runline("[opts] texture [texture ...] output.egg");
  43. add_runline("[opts] -o output.egg texture [texture ...]");
  44. add_runline("[opts] texture [texture ...] >output.egg");
  45. add_option
  46. ("g", "left,right,bottom,top", 0,
  47. "Specifies the geometry of each polygon. The default is a unit polygon "
  48. "centered on the origin: -0.5,0.5,-0.5,0.5. Polygons are always created "
  49. "on the X-Y plane. If -p is not also specified, all polygons will be "
  50. "the same size and shape.",
  51. &EggTextureCards::dispatch_double_quad, NULL, &_polygon_geometry[0]);
  52. add_option
  53. ("p", "xpixels,ypixels", 0,
  54. "Indicates that polygons should be sized in proportion to the pixel "
  55. "size of the texture image. This will potentially create a "
  56. "different size and shape polygon for each texture. The coordinate "
  57. "pair represents the image size in "
  58. "pixels that will exactly fill up the polygon described with -g (or the "
  59. "default polygon if -g is not specified); smaller images will be "
  60. "given proportionately smaller polygons, and larger images will be "
  61. "given proportionately larger polygons.",
  62. &EggTextureCards::dispatch_double_pair, &_got_pixel_scale, &_pixel_scale[0]);
  63. add_option
  64. ("c", "r,g,b[,a]", 0,
  65. "Specifies the color of each polygon. The default is white: 1,1,1,1.",
  66. &EggTextureCards::dispatch_color, NULL, &_polygon_color[0]);
  67. add_option
  68. ("wm", "[repeat | clamp]", 0,
  69. "Indicates the wrap mode of the texture: either \"repeat\" or \"clamp\" "
  70. "(or \"r\" or \"c\"). The default is to leave this unspecified.",
  71. &EggTextureCards::dispatch_wrap_mode, NULL, &_wrap_mode);
  72. add_option
  73. ("f", "format", 0,
  74. "Indicates the format of the texture: typical choices are \"rgba12\" "
  75. "or \"rgb5\" or \"alpha\". The default is to leave this unspecified.",
  76. &EggTextureCards::dispatch_format, NULL, &_format);
  77. add_option
  78. ("b", "", 0,
  79. "Make the textured polygons backfaced",
  80. &EggTextureCards::dispatch_none, &_apply_bface);
  81. _polygon_geometry.set(-0.5, 0.5, -0.5, 0.5);
  82. _polygon_color.set(1.0, 1.0, 1.0, 1.0);
  83. _wrap_mode = EggTexture::WM_unspecified;
  84. _format = EggTexture::F_unspecified;
  85. }
  86. ////////////////////////////////////////////////////////////////////
  87. // Function: EggTextureCards::handle_args
  88. // Access: Protected, Virtual
  89. // Description: Does something with the additional arguments on the
  90. // command line (after all the -options have been
  91. // parsed). Returns true if the arguments are good,
  92. // false otherwise.
  93. ////////////////////////////////////////////////////////////////////
  94. bool EggTextureCards::
  95. handle_args(ProgramBase::Args &args) {
  96. if (!check_last_arg(args, 0)) {
  97. return false;
  98. }
  99. if (args.empty()) {
  100. nout << "No texture names specified on the command line.\n";
  101. return false;
  102. }
  103. copy(args.begin(), args.end(),
  104. back_inserter(_texture_names));
  105. return true;
  106. }
  107. ////////////////////////////////////////////////////////////////////
  108. // Function: EggTextureCards::dispatch_wrap_mode
  109. // Access: Protected, Static
  110. // Description: Standard dispatch function for an option that takes
  111. // one parameter, which is to be interpreted as a
  112. // WrapMode string. The data pointer is to a WrapMode
  113. // enum variable.
  114. ////////////////////////////////////////////////////////////////////
  115. bool EggTextureCards::
  116. dispatch_wrap_mode(const string &opt, const string &arg, void *var) {
  117. EggTexture::WrapMode *wmp = (EggTexture::WrapMode *)var;
  118. *wmp = EggTexture::string_wrap_mode(arg);
  119. if (*wmp == EggTexture::WM_unspecified) {
  120. // An unknown string. Let's check for our special cases.
  121. if (arg == "r") {
  122. *wmp = EggTexture::WM_repeat;
  123. } else if (arg == "c") {
  124. *wmp = EggTexture::WM_clamp;
  125. } else {
  126. nout << "Invalid wrap mode parameter for -" << opt << ": "
  127. << arg << "\n";
  128. return false;
  129. }
  130. }
  131. return true;
  132. }
  133. ////////////////////////////////////////////////////////////////////
  134. // Function: EggTextureCards::dispatch_format
  135. // Access: Protected, Static
  136. // Description: Standard dispatch function for an option that takes
  137. // one parameter, which is to be interpreted as a
  138. // Format string. The data pointer is to a Format
  139. // enum variable.
  140. ////////////////////////////////////////////////////////////////////
  141. bool EggTextureCards::
  142. dispatch_format(const string &opt, const string &arg, void *var) {
  143. EggTexture::Format *fp = (EggTexture::Format *)var;
  144. *fp = EggTexture::string_format(arg);
  145. if (*fp == EggTexture::F_unspecified) {
  146. nout << "Invalid format parameter for -" << opt << ": "
  147. << arg << "\n";
  148. return false;
  149. }
  150. return true;
  151. }
  152. ////////////////////////////////////////////////////////////////////
  153. // Function: EggTextureCards::scan_texture
  154. // Access: Private
  155. // Description: Reads the texture image header to determine its size,
  156. // and based on this size, computes the appropriate
  157. // left,right,bottom,top geometry of the card that
  158. // correspond to this texture.
  159. //
  160. // Returns true if successful, or false if the texture
  161. // cannot be read.
  162. ////////////////////////////////////////////////////////////////////
  163. bool EggTextureCards::
  164. scan_texture(const Filename &filename, LVecBase4d &geometry) {
  165. PNMImageHeader header;
  166. if (!header.read_header(filename)) {
  167. nout << "Unable to read image " << filename << "\n";
  168. return false;
  169. }
  170. double xscale = header.get_x_size() / _pixel_scale[0];
  171. double yscale = header.get_y_size() / _pixel_scale[1];
  172. geometry.set(_polygon_geometry[0] * xscale,
  173. _polygon_geometry[1] * xscale,
  174. _polygon_geometry[2] * yscale,
  175. _polygon_geometry[3] * yscale);
  176. return true;
  177. }
  178. ////////////////////////////////////////////////////////////////////
  179. // Function: EggTextureCards::make_vertices
  180. // Access: Private
  181. // Description: Creates a set of four vertices for the polygon
  182. // according to the left,right,bottom,top geometry.
  183. ////////////////////////////////////////////////////////////////////
  184. void EggTextureCards::
  185. make_vertices(const LPoint4d &geometry, EggVertexPool *vpool,
  186. EggVertex *&v1, EggVertex *&v2, EggVertex *&v3, EggVertex *&v4) {
  187. //
  188. // 1 4
  189. //
  190. //
  191. // 2 3
  192. //
  193. v1 = vpool->make_new_vertex
  194. (LPoint3d(geometry[0], geometry[3], 0.0));
  195. v2 = vpool->make_new_vertex
  196. (LPoint3d(geometry[0], geometry[2], 0.0));
  197. v3 = vpool->make_new_vertex
  198. (LPoint3d(geometry[1], geometry[2], 0.0));
  199. v4 = vpool->make_new_vertex
  200. (LPoint3d(geometry[1], geometry[3], 0.0));
  201. v1->set_uv(TexCoordd(0.0, 1.0));
  202. v2->set_uv(TexCoordd(0.0, 0.0));
  203. v3->set_uv(TexCoordd(1.0, 0.0));
  204. v4->set_uv(TexCoordd(1.0, 1.0));
  205. }
  206. ////////////////////////////////////////////////////////////////////
  207. // Function: EggTextureCards::run
  208. // Access: Public
  209. // Description:
  210. ////////////////////////////////////////////////////////////////////
  211. void EggTextureCards::
  212. run() {
  213. // First, create an enclosing group and a vertex pool with four
  214. // vertices. We can use the same four vertices on all polygons.
  215. EggGroup *group = new EggGroup();
  216. _data.add_child(group);
  217. // If we have more than one tile, make the group a sequence, as a
  218. // convenience. If we view the egg file directly we can see all the
  219. // tiles one at a time.
  220. if (_texture_names.size() > 1) {
  221. group->set_switch_flag(true);
  222. group->set_switch_fps(2.0);
  223. }
  224. EggVertexPool *vpool = new EggVertexPool("vpool");
  225. group->add_child(vpool);
  226. EggVertex *v1, *v2, *v3, *v4;
  227. if (!_got_pixel_scale) {
  228. // If we don't have a per-texture pixel scale, all the polygons
  229. // will be the same size, and hence may all share the same four
  230. // vertices.
  231. make_vertices(_polygon_geometry, vpool, v1, v2, v3, v4);
  232. }
  233. // Now, create a texture reference and a polygon for each texture.
  234. vector_string::const_iterator ti;
  235. for (ti = _texture_names.begin(); ti != _texture_names.end(); ++ti) {
  236. Filename filename = (*ti);
  237. string name = filename.get_basename_wo_extension();
  238. bool texture_ok = true;
  239. if (_got_pixel_scale) {
  240. // If we have a per-texture pixel scale, we have to read in the
  241. // texture header and determine its size.
  242. LVecBase4d geometry;
  243. texture_ok = scan_texture(filename, geometry);
  244. if (texture_ok) {
  245. make_vertices(geometry, vpool, v1, v2, v3, v4);
  246. }
  247. }
  248. if (texture_ok) {
  249. EggTexture *tref = new EggTexture(name, filename);
  250. tref->set_wrap_mode(_wrap_mode);
  251. tref->set_format(_format);
  252. group->add_child(tref);
  253. // Each polygon gets placed in its own sub-group. This will make
  254. // pulling them out by name at runtime possible.
  255. EggGroup *sub_group = new EggGroup(name);
  256. group->add_child(sub_group);
  257. EggPolygon *poly = new EggPolygon();
  258. sub_group->add_child(poly);
  259. poly->set_texture(tref);
  260. poly->set_color(_polygon_color);
  261. if (_apply_bface){
  262. poly->set_bface_flag(1);
  263. }
  264. poly->add_vertex(v1);
  265. poly->add_vertex(v2);
  266. poly->add_vertex(v3);
  267. poly->add_vertex(v4);
  268. }
  269. }
  270. // Done!
  271. write_egg_file();
  272. }
  273. int main(int argc, char *argv[]) {
  274. EggTextureCards prog;
  275. prog.parse_command_line(argc, argv);
  276. prog.run();
  277. return 0;
  278. }