eggToFlt.cxx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  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 eggToFlt.cxx
  10. * @author drose
  11. * @date 2003-10-01
  12. */
  13. #include "eggToFlt.h"
  14. #include "fltHeader.h"
  15. #include "fltBead.h"
  16. #include "fltGroup.h"
  17. #include "fltFace.h"
  18. #include "fltVertexList.h"
  19. #include "fltVertex.h"
  20. #include "fltTexture.h"
  21. #include "fltTransformTranslate.h"
  22. #include "fltTransformRotateAboutEdge.h"
  23. #include "fltTransformScale.h"
  24. #include "fltTransformGeneralMatrix.h"
  25. #include "eggPolygon.h"
  26. #include "eggPoint.h"
  27. #include "eggPrimitive.h"
  28. #include "eggExternalReference.h"
  29. #include "eggGroup.h"
  30. #include "eggGroupNode.h"
  31. #include "eggTexture.h"
  32. #include "eggTransform.h"
  33. #include "dcast.h"
  34. #include "string_utils.h"
  35. #include "vector_string.h"
  36. /**
  37. *
  38. */
  39. EggToFlt::
  40. EggToFlt() :
  41. EggToSomething("MultiGen", ".flt", true, false)
  42. {
  43. set_binary_output(true);
  44. set_program_brief("convert files from .egg format to MultiGen .flt");
  45. set_program_description
  46. ("egg2lt converts files from egg format to MultiGen .flt "
  47. "format. It attempts to be as robust as possible, and matches "
  48. "the capabilities of flt2egg. Generally, converting a model "
  49. "from egg2lt and then back via flt2egg will result in essentially "
  50. "the same egg file, within the limitations of what can be "
  51. "represented in flt.");
  52. add_option
  53. ("attr", "none/new/all", 0,
  54. "Specifies whether to write (or rewrite) .attr files for each "
  55. "texture image. MultiGen stores texture properties like mipmapping "
  56. "in a separate .attr file for each different texture image. "
  57. "If this parameter is \"none\", these files will not be generated; "
  58. "if this is \"new\", these files will only be generated if they "
  59. "do not already exist (even if the properties have changed). "
  60. "Specifying \"all\" causes these to be rewritten every time.",
  61. &EggToFlt::dispatch_attr, nullptr, &_auto_attr_update);
  62. // Flt files are always in the z-up coordinate system. Don't confuse the
  63. // user with this meaningless option.
  64. remove_option("cs");
  65. _coordinate_system = CS_zup_right;
  66. _got_coordinate_system = true;
  67. _auto_attr_update = FltHeader::AU_if_missing;
  68. }
  69. /**
  70. *
  71. */
  72. void EggToFlt::
  73. run() {
  74. _flt_header = new FltHeader(_path_replace);
  75. _flt_header->set_auto_attr_update(_auto_attr_update);
  76. traverse(_data, _flt_header, FltGeometry::BT_none);
  77. // Finally, write the resulting file out.
  78. FltError result = _flt_header->write_flt(get_output());
  79. if (result != FE_ok) {
  80. nout << "Cannot write " << get_output_filename() << "\n";
  81. exit(1);
  82. }
  83. }
  84. /**
  85. * Dispatch function for the -attr parameter.
  86. */
  87. bool EggToFlt::
  88. dispatch_attr(const std::string &opt, const std::string &arg, void *var) {
  89. FltHeader::AttrUpdate *ip = (FltHeader::AttrUpdate *)var;
  90. if (cmp_nocase(arg, "none") == 0) {
  91. *ip = FltHeader::AU_none;
  92. } else if (cmp_nocase(arg, "new") == 0) {
  93. *ip = FltHeader::AU_if_missing;
  94. } else if (cmp_nocase(arg, "all") == 0) {
  95. *ip = FltHeader::AU_always;
  96. } else {
  97. nout << "-" << opt
  98. << " requires either \"none\", \"new\", or \"all\".\n";
  99. return false;
  100. }
  101. return true;
  102. }
  103. /**
  104. *
  105. */
  106. void EggToFlt::
  107. traverse(EggNode *egg_node, FltBead *flt_node,
  108. FltGeometry::BillboardType billboard) {
  109. if (egg_node->is_of_type(EggPolygon::get_class_type()) ||
  110. egg_node->is_of_type(EggPoint::get_class_type())) {
  111. // It's a polygon or point light.
  112. EggPrimitive *egg_primitive = DCAST(EggPrimitive, egg_node);
  113. convert_primitive(egg_primitive, flt_node, billboard);
  114. } else if (egg_node->is_of_type(EggExternalReference::get_class_type())) {
  115. // Convert external references.
  116. } else if (egg_node->is_of_type(EggGroup::get_class_type())) {
  117. // An EggGroup creates a fltBead, and recurses.
  118. EggGroup *egg_group = DCAST(EggGroup, egg_node);
  119. if (egg_group->get_group_type() == EggGroup::GT_joint) {
  120. // Ignore joints and their children.
  121. return;
  122. }
  123. convert_group(egg_group, flt_node, billboard);
  124. } else if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
  125. // Some kind of grouping node other than an EggGroup. Just recurse.
  126. EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
  127. EggGroupNode::iterator ci;
  128. for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  129. traverse(*ci, flt_node, billboard);
  130. }
  131. }
  132. }
  133. /**
  134. * Converts an egg polygon or series of light points to the corresponding Flt
  135. * geometry, and adds it to the indicated flt_node.
  136. */
  137. void EggToFlt::
  138. convert_primitive(EggPrimitive *egg_primitive, FltBead *flt_node,
  139. FltGeometry::BillboardType billboard) {
  140. FltFace *flt_face = new FltFace(_flt_header);
  141. flt_node->add_child(flt_face);
  142. flt_face->_billboard_type = billboard;
  143. if (egg_primitive->has_color()) {
  144. flt_face->set_color(egg_primitive->get_color());
  145. }
  146. if (egg_primitive->is_of_type(EggPoint::get_class_type())) {
  147. // A series of points, instead of a polygon.
  148. flt_face->_draw_type = FltFace::DT_omni_light;
  149. } else if (egg_primitive->get_bface_flag()) {
  150. // A polygon whose backface is visible.
  151. flt_face->_draw_type = FltFace::DT_solid_no_cull;
  152. } else {
  153. // A normal polygon.
  154. flt_face->_draw_type = FltFace::DT_solid_cull_backface;
  155. }
  156. if (egg_primitive->has_texture()) {
  157. EggTexture *egg_texture = egg_primitive->get_texture();
  158. FltTexture *flt_texture = get_flt_texture(egg_texture);
  159. flt_face->set_texture(flt_texture);
  160. }
  161. // Create a vertex list representing the vertices in the primitive, and add
  162. // it as a child of the face bead. This is how Flt files associate vertices
  163. // with faces.
  164. FltVertexList *flt_vertices = new FltVertexList(_flt_header);
  165. flt_face->add_child(flt_vertices);
  166. EggPrimitive::iterator vi;
  167. bool all_verts_have_color = true;
  168. bool all_verts_have_normal = true;
  169. for (vi = egg_primitive->begin(); vi != egg_primitive->end(); ++vi) {
  170. EggVertex *egg_vertex = (*vi);
  171. FltVertex *flt_vertex = get_flt_vertex(egg_vertex, egg_primitive);
  172. flt_vertices->add_vertex(flt_vertex);
  173. if (!egg_vertex->has_color()) {
  174. all_verts_have_color = false;
  175. }
  176. if (!egg_vertex->has_normal()) {
  177. all_verts_have_normal = false;
  178. }
  179. }
  180. if (all_verts_have_color) {
  181. // If all the vertices of the face have a color specification, then we
  182. // specify per-vertex color on the face.
  183. if (all_verts_have_normal) {
  184. // And similarly with the normals.
  185. flt_face->_light_mode = FltFace::LM_vertex_with_normal;
  186. } else {
  187. flt_face->_light_mode = FltFace::LM_vertex_no_normal;
  188. }
  189. } else {
  190. if (all_verts_have_normal) {
  191. flt_face->_light_mode = FltFace::LM_face_with_normal;
  192. } else {
  193. flt_face->_light_mode = FltFace::LM_face_no_normal;
  194. }
  195. }
  196. }
  197. /**
  198. * Converts an egg group to the corresponding flt group, and adds it to the
  199. * indicated parent node. Also recurses on the children of the egg group.
  200. */
  201. void EggToFlt::
  202. convert_group(EggGroup *egg_group, FltBead *flt_node,
  203. FltGeometry::BillboardType billboard) {
  204. std::ostringstream egg_syntax;
  205. FltGroup *flt_group = new FltGroup(_flt_header);
  206. flt_node->add_child(flt_group);
  207. flt_group->set_id(egg_group->get_name());
  208. switch (egg_group->get_billboard_type()) {
  209. // MultiGen represents billboarding at the polygon level, so we have to
  210. // remember this flag for later.
  211. case EggGroup::BT_axis:
  212. billboard = FltGeometry::BT_axial;
  213. break;
  214. case EggGroup::BT_point_world_relative:
  215. billboard = FltGeometry::BT_point;
  216. break;
  217. case EggGroup::BT_point_camera_relative:
  218. // Not sure if this is the right flag for MultiGen.
  219. billboard = FltGeometry::BT_fixed;
  220. break;
  221. default:
  222. break;
  223. }
  224. if (egg_group->has_transform()) {
  225. apply_transform(egg_group, flt_group);
  226. }
  227. if (egg_group->get_switch_flag()) {
  228. if (egg_group->get_switch_fps() != 0.0) {
  229. // A sequence animation.
  230. flt_group->_flags |= FltGroup::F_forward_animation;
  231. egg_syntax
  232. << " <Scalar> fps { " << egg_group->get_switch_fps() << " }\n";
  233. } else {
  234. // Just a switch node.
  235. egg_group->write_switch_flags(egg_syntax, 2);
  236. }
  237. }
  238. // Pick up any additional egg attributes that MultiGen doesn't support;
  239. // these will get written to the comment field where flt2egg will find it.
  240. egg_group->write_collide_flags(egg_syntax, 2);
  241. egg_group->write_model_flags(egg_syntax, 2);
  242. egg_group->write_object_types(egg_syntax, 2);
  243. egg_group->write_decal_flags(egg_syntax, 2);
  244. egg_group->write_tags(egg_syntax, 2);
  245. egg_group->write_render_mode(egg_syntax, 2);
  246. apply_egg_syntax(egg_syntax.str(), flt_group);
  247. EggGroup::iterator ci;
  248. for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
  249. traverse(*ci, flt_group, billboard);
  250. }
  251. }
  252. /**
  253. * Applies the indicated egg transform to the indicated flt bead.
  254. */
  255. void EggToFlt::
  256. apply_transform(EggTransform *egg_transform, FltBead *flt_node) {
  257. flt_node->clear_transform();
  258. bool components_ok = true;
  259. int num_components = egg_transform->get_num_components();
  260. for (int i = num_components - 1; i >= 0 && components_ok; i--) {
  261. switch (egg_transform->get_component_type(i)) {
  262. case EggTransform::CT_translate2d:
  263. {
  264. FltTransformTranslate *translate =
  265. new FltTransformTranslate(_flt_header);
  266. LVector2d v2 = egg_transform->get_component_vec2(i);
  267. translate->set(LPoint3d::zero(), LVector3d(v2[0], v2[1], 0.0));
  268. flt_node->add_transform_step(translate);
  269. }
  270. break;
  271. case EggTransform::CT_translate3d:
  272. {
  273. FltTransformTranslate *translate =
  274. new FltTransformTranslate(_flt_header);
  275. translate->set(LPoint3d::zero(), egg_transform->get_component_vec3(i));
  276. flt_node->add_transform_step(translate);
  277. }
  278. break;
  279. case EggTransform::CT_rotate2d:
  280. {
  281. FltTransformRotateAboutEdge *rotate =
  282. new FltTransformRotateAboutEdge(_flt_header);
  283. rotate->set(LPoint3d::zero(), LPoint3d(0.0, 0.0, 1.0),
  284. egg_transform->get_component_number(i));
  285. flt_node->add_transform_step(rotate);
  286. }
  287. break;
  288. case EggTransform::CT_rotx:
  289. {
  290. FltTransformRotateAboutEdge *rotate =
  291. new FltTransformRotateAboutEdge(_flt_header);
  292. rotate->set(LPoint3d::zero(), LPoint3d(1.0, 0.0, 0.0),
  293. egg_transform->get_component_number(i));
  294. flt_node->add_transform_step(rotate);
  295. }
  296. break;
  297. case EggTransform::CT_roty:
  298. {
  299. FltTransformRotateAboutEdge *rotate =
  300. new FltTransformRotateAboutEdge(_flt_header);
  301. rotate->set(LPoint3d::zero(), LPoint3d(0.0, 1.0, 0.0),
  302. egg_transform->get_component_number(i));
  303. flt_node->add_transform_step(rotate);
  304. }
  305. break;
  306. case EggTransform::CT_rotz:
  307. {
  308. FltTransformRotateAboutEdge *rotate =
  309. new FltTransformRotateAboutEdge(_flt_header);
  310. rotate->set(LPoint3d::zero(), LPoint3d(0.0, 0.0, 1.0),
  311. egg_transform->get_component_number(i));
  312. flt_node->add_transform_step(rotate);
  313. }
  314. break;
  315. case EggTransform::CT_rotate3d:
  316. {
  317. FltTransformRotateAboutEdge *rotate =
  318. new FltTransformRotateAboutEdge(_flt_header);
  319. rotate->set(LPoint3d::zero(), egg_transform->get_component_vec3(i),
  320. egg_transform->get_component_number(i));
  321. flt_node->add_transform_step(rotate);
  322. }
  323. break;
  324. case EggTransform::CT_scale2d:
  325. {
  326. FltTransformScale *scale = new FltTransformScale(_flt_header);
  327. LVector2d v2 = egg_transform->get_component_vec2(i);
  328. scale->set(LPoint3d::zero(), LVector3(v2[0], v2[1], 1.0f));
  329. flt_node->add_transform_step(scale);
  330. }
  331. break;
  332. case EggTransform::CT_scale3d:
  333. {
  334. FltTransformScale *scale = new FltTransformScale(_flt_header);
  335. scale->set(LPoint3d::zero(), LCAST(PN_stdfloat, egg_transform->get_component_vec3(i)));
  336. flt_node->add_transform_step(scale);
  337. }
  338. break;
  339. case EggTransform::CT_uniform_scale:
  340. {
  341. FltTransformScale *scale = new FltTransformScale(_flt_header);
  342. PN_stdfloat factor = (PN_stdfloat)egg_transform->get_component_number(i);
  343. scale->set(LPoint3d::zero(), LVecBase3(factor, factor, factor));
  344. flt_node->add_transform_step(scale);
  345. }
  346. break;
  347. case EggTransform::CT_matrix3:
  348. {
  349. FltTransformGeneralMatrix *matrix =
  350. new FltTransformGeneralMatrix(_flt_header);
  351. const LMatrix3d &m = egg_transform->get_component_mat3(i);
  352. LMatrix4d mat4(m(0, 0), m(0, 1), 0.0, m(0, 2),
  353. m(1, 0), m(1, 1), 0.0, m(1, 2),
  354. 0.0, 0.0, 1.0, 0.0,
  355. m(2, 0), m(2, 1), 0.0, m(2, 2));
  356. matrix->set_matrix(mat4);
  357. flt_node->add_transform_step(matrix);
  358. }
  359. break;
  360. case EggTransform::CT_matrix4:
  361. {
  362. FltTransformGeneralMatrix *matrix =
  363. new FltTransformGeneralMatrix(_flt_header);
  364. matrix->set_matrix(egg_transform->get_component_mat4(i));
  365. flt_node->add_transform_step(matrix);
  366. }
  367. break;
  368. default:
  369. // Don't know how to convert this component.
  370. components_ok = false;
  371. }
  372. }
  373. if (components_ok) {
  374. // Verify that the transform was computed correctly.
  375. if (!flt_node->get_transform().almost_equal(egg_transform->get_transform3d())) {
  376. nout << "Incorrect transform! Expected:\n";
  377. egg_transform->get_transform3d().write(nout, 2);
  378. nout << "Computed:\n";
  379. flt_node->get_transform().write(nout, 2);
  380. nout << "\n";
  381. components_ok = false;
  382. }
  383. }
  384. if (!components_ok) {
  385. // Just store the overall transform.
  386. flt_node->set_transform(egg_transform->get_transform3d());
  387. }
  388. }
  389. /**
  390. * Adds the indicated sequence of egg syntax lines (presumably representing
  391. * egg features not directly supported by MultiGen) to the flt record as a
  392. * comment, so that flt2egg will reapply it to the egg groups.
  393. */
  394. void EggToFlt::
  395. apply_egg_syntax(const std::string &egg_syntax, FltRecord *flt_record) {
  396. if (!egg_syntax.empty()) {
  397. std::ostringstream out;
  398. out << "<egg> {\n"
  399. << egg_syntax
  400. << "}";
  401. flt_record->set_comment(out.str());
  402. }
  403. }
  404. /**
  405. * Returns a FltVertex corresponding to the indicated EggVertex. If the
  406. * vertex has not been seen before (in this particular vertex frame), creates
  407. * a new one.
  408. */
  409. FltVertex *EggToFlt::
  410. get_flt_vertex(EggVertex *egg_vertex, EggNode *context) {
  411. const LMatrix4d *frame = context->get_vertex_to_node_ptr();
  412. VertexMap &vertex_map = _vertex_map_per_frame[frame];
  413. VertexMap::iterator vi = vertex_map.find(egg_vertex);
  414. if (vi != vertex_map.end()) {
  415. return (*vi).second;
  416. }
  417. FltVertex *flt_vertex = new FltVertex(_flt_header);
  418. flt_vertex->_pos = egg_vertex->get_pos3();
  419. if (egg_vertex->has_color()) {
  420. flt_vertex->set_color(egg_vertex->get_color());
  421. }
  422. if (egg_vertex->has_normal()) {
  423. flt_vertex->_normal = LCAST(PN_stdfloat, egg_vertex->get_normal());
  424. flt_vertex->_has_normal = true;
  425. }
  426. if (egg_vertex->has_uv()) {
  427. flt_vertex->_uv = LCAST(PN_stdfloat, egg_vertex->get_uv());
  428. flt_vertex->_has_uv = true;
  429. }
  430. if (frame != nullptr) {
  431. flt_vertex->_pos = flt_vertex->_pos * (*frame);
  432. flt_vertex->_normal = flt_vertex->_normal * LCAST(PN_stdfloat, (*frame));
  433. }
  434. _flt_header->add_vertex(flt_vertex);
  435. vertex_map[egg_vertex] = flt_vertex;
  436. return flt_vertex;
  437. }
  438. /**
  439. * Returns a FltTexture corresponding to the indicated EggTexture. If the
  440. * texture has not been seen before, creates a new one.
  441. */
  442. FltTexture *EggToFlt::
  443. get_flt_texture(EggTexture *egg_texture) {
  444. // We have to maintain this map based on the filename, not the egg pointer,
  445. // because there may be multiple EggTextures with the same filename, and we
  446. // have to collapse them together.
  447. Filename filename = egg_texture->get_filename();
  448. TextureMap::iterator vi = _texture_map.find(filename);
  449. if (vi != _texture_map.end()) {
  450. return (*vi).second;
  451. }
  452. FltTexture *flt_texture = new FltTexture(_flt_header);
  453. flt_texture->set_texture_filename(filename);
  454. switch (egg_texture->get_minfilter()) {
  455. case EggTexture::FT_nearest:
  456. flt_texture->_min_filter = FltTexture::MN_point;
  457. break;
  458. case EggTexture::FT_linear:
  459. flt_texture->_min_filter = FltTexture::MN_bilinear;
  460. break;
  461. case EggTexture::FT_nearest_mipmap_nearest:
  462. flt_texture->_min_filter = FltTexture::MN_mipmap_point;
  463. break;
  464. case EggTexture::FT_nearest_mipmap_linear:
  465. flt_texture->_min_filter = FltTexture::MN_mipmap_linear;
  466. break;
  467. case EggTexture::FT_linear_mipmap_nearest:
  468. flt_texture->_min_filter = FltTexture::MN_mipmap_bilinear;
  469. break;
  470. case EggTexture::FT_linear_mipmap_linear:
  471. flt_texture->_min_filter = FltTexture::MN_mipmap_trilinear;
  472. break;
  473. default:
  474. break;
  475. }
  476. switch (egg_texture->get_magfilter()) {
  477. case EggTexture::FT_nearest:
  478. flt_texture->_mag_filter = FltTexture::MG_point;
  479. break;
  480. case EggTexture::FT_linear:
  481. flt_texture->_mag_filter = FltTexture::MG_bilinear;
  482. break;
  483. default:
  484. break;
  485. }
  486. switch (egg_texture->get_wrap_mode()) {
  487. case EggTexture::WM_repeat:
  488. flt_texture->_repeat = FltTexture::RT_repeat;
  489. break;
  490. case EggTexture::WM_clamp:
  491. flt_texture->_repeat = FltTexture::RT_clamp;
  492. break;
  493. default:
  494. break;
  495. }
  496. switch (egg_texture->get_wrap_u()) {
  497. case EggTexture::WM_repeat:
  498. flt_texture->_repeat_u = FltTexture::RT_repeat;
  499. break;
  500. case EggTexture::WM_clamp:
  501. flt_texture->_repeat_u = FltTexture::RT_clamp;
  502. break;
  503. default:
  504. break;
  505. }
  506. switch (egg_texture->get_wrap_v()) {
  507. case EggTexture::WM_repeat:
  508. flt_texture->_repeat_v = FltTexture::RT_repeat;
  509. break;
  510. case EggTexture::WM_clamp:
  511. flt_texture->_repeat_v = FltTexture::RT_clamp;
  512. break;
  513. default:
  514. break;
  515. }
  516. switch (egg_texture->get_env_type()) {
  517. case EggTexture::ET_modulate:
  518. flt_texture->_env_type = FltTexture::ET_modulate;
  519. break;
  520. case EggTexture::ET_decal:
  521. flt_texture->_env_type = FltTexture::ET_decal;
  522. break;
  523. default:
  524. break;
  525. }
  526. switch (egg_texture->get_format()) {
  527. case EggTexture::F_luminance_alpha:
  528. case EggTexture::F_luminance_alphamask:
  529. flt_texture->_internal_format = FltTexture::IF_ia_8;
  530. break;
  531. case EggTexture::F_rgb5:
  532. case EggTexture::F_rgb332:
  533. flt_texture->_internal_format = FltTexture::IF_rgb_5;
  534. break;
  535. case EggTexture::F_rgba4:
  536. case EggTexture::F_rgba5:
  537. flt_texture->_internal_format = FltTexture::IF_rgba_4;
  538. break;
  539. case EggTexture::F_rgba8:
  540. case EggTexture::F_rgba:
  541. case EggTexture::F_rgbm:
  542. case EggTexture::F_rgb:
  543. case EggTexture::F_rgb8:
  544. flt_texture->_internal_format = FltTexture::IF_rgba_8;
  545. break;
  546. case EggTexture::F_rgba12:
  547. flt_texture->_internal_format = FltTexture::IF_rgba_12;
  548. break;
  549. case EggTexture::F_alpha:
  550. flt_texture->_internal_format = FltTexture::IF_i_16;
  551. flt_texture->_intensity_is_alpha = true;
  552. break;
  553. case EggTexture::F_luminance:
  554. flt_texture->_internal_format = FltTexture::IF_i_16;
  555. break;
  556. case EggTexture::F_rgb12:
  557. flt_texture->_internal_format = FltTexture::IF_rgb_12;
  558. break;
  559. default:
  560. break;
  561. }
  562. _flt_header->add_texture(flt_texture);
  563. _texture_map[filename] = flt_texture;
  564. return flt_texture;
  565. }
  566. int main(int argc, char *argv[]) {
  567. EggToFlt prog;
  568. prog.parse_command_line(argc, argv);
  569. prog.run();
  570. return 0;
  571. }