texgen.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:12k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /*
  2.  * texgen.c
  3.  *
  4.  * FUNCTION:
  5.  * texture mapping hack
  6.  *
  7.  * HISTORY:
  8.  * Created by Linas Vepstas April 1994
  9.  * general cleanup December 1995
  10.  */
  11. #include <stdlib.h>
  12. #include <math.h>
  13. #include <GL/tube.h>
  14. #include "port.h"
  15. #include "tube_gc.h"
  16. /* ======================================================= */
  17. gleGC *_gle_gc = 0x0;
  18. gleGC * gleCreateGC (void) {
  19.    gleGC * retval = (gleGC *) malloc (sizeof (gleGC));
  20.    retval -> bgn_gen_texture = 0x0;
  21.    retval -> n3f_gen_texture = 0x0;
  22.    retval -> n3d_gen_texture = 0x0;
  23.    retval -> v3f_gen_texture = 0x0;
  24.    retval -> v3d_gen_texture = 0x0;
  25.    retval -> end_gen_texture = 0x0;
  26.    retval -> save_bgn_gen_texture = 0x0;
  27.    retval -> save_n3f_gen_texture = 0x0;
  28.    retval -> save_n3d_gen_texture = 0x0;
  29.    retval -> save_v3f_gen_texture = 0x0;
  30.    retval -> save_v3d_gen_texture = 0x0;
  31.    retval -> save_end_gen_texture = 0x0;
  32.    retval -> join_style = TUBE_JN_ANGLE | TUBE_JN_CAP | TUBE_NORM_FACET;
  33.    retval -> ncp = 0;
  34.    retval -> npoints = 0;
  35.    retval -> num_vert = 0;
  36.    retval -> segment_number = 0;
  37.    retval -> segment_length = 0.0;
  38.    retval -> accum_seg_len = 0.0;
  39.    retval -> prev_x = 0.0;
  40.    retval -> prev_y = 0.0;
  41.    return retval;
  42. }
  43. /* ======================================================= */
  44. #define segment_number (_gle_gc -> segment_number)
  45. #define segment_length (_gle_gc -> segment_length)
  46. #define accum_seg_len (_gle_gc -> accum_seg_len)
  47. #define num_vert  (_gle_gc -> num_vert)
  48. #define prev_x  (_gle_gc -> prev_x)
  49. #define prev_y  (_gle_gc -> prev_y)
  50. /* ======================================================= */
  51. static double save_nx = 0.0;
  52. static double save_ny = 0.0;
  53. static double save_nz = 0.0;
  54. static void save_normal (double *v) {
  55.    save_nx = v[0];
  56.    save_ny = v[1];
  57.    save_nz = v[2];
  58. }
  59. /* ======================================================= */
  60. static void bgn_sphere_texgen (int inext, double len) {
  61.    segment_number = inext - 1;
  62.    segment_length = len;
  63.    num_vert = 0;
  64. }
  65. /* ======================================================= */
  66. /* 
  67.  * this routine assumes that the vertex passed in has been normalized
  68.  * (i.e. is of unit length)
  69.  */
  70. /* ARGSUSED3 */
  71. static void sphere_texgen (double x, double y, double z,
  72.                            int jcnt, int which_end) 
  73. {
  74.    double theta, phi;
  75.    /* let phi and theta range fro 0 to 1 */
  76.    phi = 0.5 * atan2 (x, y) / M_PI;
  77.    phi += 0.5;
  78.    theta = 1.0 - acos (z) / M_PI;
  79.    /* if first vertex, merely record the texture coords */
  80.    if (num_vert == 0) {
  81.       prev_x = phi;
  82.       prev_y = theta;
  83.       num_vert ++;
  84.    } else {
  85.       /* if texture coordinates changed radically, wrap them */
  86.       if ((prev_y - theta) > 0.6) {
  87.          theta +=1.0;
  88.       } else if ((prev_y - theta) < -0.6) {
  89.          theta -=1.0;
  90.       } /* else no-op */
  91.       prev_y = theta;
  92.       /* if texture coordinates changed radically, wrap them */
  93.       if ((prev_x - phi) > 0.6) {
  94.          phi +=1.0;
  95.       } else if ((prev_x - phi) < -0.6) {
  96.          phi -=1.0;
  97.       } /* else no-op */
  98.       prev_x = phi;
  99.    }
  100.    T2F_D (phi, theta);
  101. }
  102. /* ======================================================= */
  103. /* mappers */
  104. static void vertex_sphere_texgen_v (double *v, int jcnt, int which_end)  {
  105.    double x = v[0]; double y = v[1]; double z = v[2];
  106.    double r;
  107.    r = 1.0 / sqrt (x*x + y*y + z*z);
  108.    x *= r;
  109.    y *= r;
  110.    z *= r;
  111.    sphere_texgen (x, y, z, jcnt, which_end);
  112. }
  113. /* ARGSUSED */
  114. static void normal_sphere_texgen_v (double *v, int jcnt, int which_end)  {
  115.    sphere_texgen (save_nx, save_ny, save_nz, jcnt, which_end);
  116. }
  117. static void vertex_sphere_model_v (double *v, int jcnt, int which_end) {
  118.    double x = _gle_gc->contour[jcnt][0]; 
  119.    double y = _gle_gc->contour[jcnt][1]; 
  120.    double z = v[2];
  121.    double r;
  122.    r = 1.0 / sqrt (x*x + y*y + z*z);
  123.    x *= r;
  124.    y *= r;
  125.    z *= r;
  126.    sphere_texgen (x, y, z, jcnt, which_end);
  127. }
  128. /* ARGSUSED */
  129. static void normal_sphere_model_v (double *v, int jcnt, int which_end) {
  130.    if (!(_gle_gc -> cont_normal)) return;
  131.    sphere_texgen (_gle_gc->cont_normal[jcnt][0], 
  132.                 _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end);
  133. }
  134. /* ======================================================= */
  135. static void bgn_z_texgen (int inext, double len) {
  136.    /* accumulate the previous length */
  137.    accum_seg_len += segment_length;
  138.    /* save current values */
  139.    segment_number = inext - 1;
  140.    segment_length = len;
  141.    /* reset counter on first segment */
  142.    if (1 >= segment_number) accum_seg_len = 0.0;
  143.    num_vert = 0;
  144. }
  145. /* ======================================================= */
  146. /* ARGSUSED2 */
  147. static void cylinder_texgen (double x, double y, double z,
  148.                              int jcnt, int which_end) 
  149. {
  150.    double phi;
  151.    /* let phi and theta range fro 0 to 1 */
  152.    phi = 0.5 * atan2 (x, y) / M_PI;
  153.    phi += 0.5;
  154.    /* if first vertex, merely record the texture coords */
  155.    if (num_vert == 0) {
  156.       prev_x = phi;
  157.       num_vert ++;
  158.    } else {
  159.       /* if texture coordinates changed radically, wrap them */
  160.       if ((prev_x - phi) > 0.6) {
  161.          phi +=1.0;
  162.       } else if ((prev_x - phi) < -0.6) {
  163.          phi -=1.0;
  164.       } /* else no-op */
  165.       prev_x = phi;
  166.    }
  167.    if (FRONT == which_end) {
  168.       T2F_D (phi, accum_seg_len);
  169.    }
  170.    if (BACK == which_end) {
  171.       T2F_D (phi, accum_seg_len + segment_length);
  172.    }
  173. }
  174. /* ======================================================= */
  175. /* mappers */
  176. static void vertex_cylinder_texgen_v (double *v, int jcnt, int which_end) {
  177.    double x = v[0]; double y = v[1]; double z = v[2];
  178.    double r;
  179.    r = 1.0 / sqrt (x*x + y*y);
  180.    x *= r;
  181.    y *= r;
  182.    cylinder_texgen (x, y, z, jcnt, which_end);
  183. }
  184. /* ARGSUSED */
  185. static void normal_cylinder_texgen_v (double *v, int jcnt, int which_end) {
  186.    cylinder_texgen (save_nx, save_ny, save_nz, jcnt, which_end);
  187. }
  188. static void vertex_cylinder_model_v (double *v, int jcnt, int which_end) {
  189.    double x = _gle_gc->contour[jcnt][0]; 
  190.    double y = _gle_gc->contour[jcnt][1]; 
  191.    double z = v[2];
  192.    double r;
  193.    r = 1.0 / sqrt (x*x + y*y);
  194.    x *= r;
  195.    y *= r;
  196.    cylinder_texgen (x, y, z, jcnt, which_end);
  197. }
  198. /* ARGSUSED */
  199. static void normal_cylinder_model_v (double *v, int jcnt, int which_end) {
  200.    if (!(_gle_gc -> cont_normal)) return;
  201.    cylinder_texgen (_gle_gc->cont_normal[jcnt][0], 
  202.                 _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end);
  203. }
  204. /* ======================================================= */
  205. /* ARGSUSED1 */
  206. static void flat_texgen (double x, double y, double z,
  207.                              int jcnt, int which_end) 
  208. {
  209.    if (FRONT == which_end) {
  210.       T2F_D (x, accum_seg_len);
  211.    }
  212.    if (BACK == which_end) {
  213.       T2F_D (x, accum_seg_len + segment_length);
  214.    }
  215. }
  216. /* ======================================================= */
  217. static void vertex_flat_texgen_v (double *v, int jcnt, int which_end) {
  218.    flat_texgen (v[0], v[1], v[2], jcnt, which_end);
  219. }
  220. /* ARGSUSED */
  221. static void normal_flat_texgen_v (double *v, int jcnt, int which_end) {
  222.    flat_texgen (save_nx, save_ny, save_nz, jcnt, which_end);
  223. }
  224. static void vertex_flat_model_v (double *v, int jcnt, int which_end) {
  225.    flat_texgen (_gle_gc->contour[jcnt][0], 
  226.                 _gle_gc->contour[jcnt][1], v[2], jcnt, which_end);
  227. }
  228. /* ARGSUSED */
  229. static void normal_flat_model_v (double *v, int jcnt, int which_end) {
  230.    if (!(_gle_gc -> cont_normal)) return;
  231.    flat_texgen (_gle_gc->cont_normal[jcnt][0], 
  232.                 _gle_gc->cont_normal[jcnt][1], 0.0, jcnt, which_end);
  233. }
  234. /* ======================================================= */
  235. void gleTextureMode (int mode) {
  236.    INIT_GC();
  237.    /* enable textureing by restoring the mode */
  238.    _gle_gc -> bgn_gen_texture = _gle_gc -> save_bgn_gen_texture; 
  239.    _gle_gc -> n3f_gen_texture = _gle_gc -> save_n3f_gen_texture; 
  240.    _gle_gc -> n3d_gen_texture = _gle_gc -> save_n3d_gen_texture; 
  241.    _gle_gc -> v3f_gen_texture = _gle_gc -> save_v3f_gen_texture; 
  242.    _gle_gc -> v3d_gen_texture = _gle_gc -> save_v3d_gen_texture; 
  243.    _gle_gc -> end_gen_texture = _gle_gc -> save_end_gen_texture; 
  244.    switch (mode&GLE_TEXTURE_STYLE_MASK) {
  245.       case GLE_TEXTURE_VERTEX_FLAT:
  246.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  247.          _gle_gc -> v3d_gen_texture = vertex_flat_texgen_v;
  248.          _gle_gc -> n3d_gen_texture = 0x0;
  249.          break;
  250.       case GLE_TEXTURE_NORMAL_FLAT:
  251.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  252.          _gle_gc -> v3d_gen_texture = normal_flat_texgen_v;
  253.          _gle_gc -> n3d_gen_texture = save_normal;
  254.          break;
  255.       case GLE_TEXTURE_VERTEX_MODEL_FLAT:
  256.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  257.          _gle_gc -> v3d_gen_texture = vertex_flat_model_v;
  258.          _gle_gc -> n3d_gen_texture = 0x0;
  259.          break;
  260.       case GLE_TEXTURE_NORMAL_MODEL_FLAT:
  261.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  262.          _gle_gc -> v3d_gen_texture = normal_flat_model_v;
  263.          _gle_gc -> n3d_gen_texture = 0x0;
  264.          break;
  265.       case GLE_TEXTURE_VERTEX_CYL:
  266.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  267.          _gle_gc -> v3d_gen_texture = vertex_cylinder_texgen_v;
  268.          _gle_gc -> n3d_gen_texture = 0x0;
  269.          break;
  270.       case GLE_TEXTURE_NORMAL_CYL:
  271.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  272.          _gle_gc -> v3d_gen_texture = normal_cylinder_texgen_v;
  273.          _gle_gc -> n3d_gen_texture = save_normal;
  274.          break;
  275.       case GLE_TEXTURE_VERTEX_MODEL_CYL:
  276.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  277.          _gle_gc -> v3d_gen_texture = vertex_cylinder_model_v;
  278.          _gle_gc -> n3d_gen_texture = 0x0;
  279.          break;
  280.       case GLE_TEXTURE_NORMAL_MODEL_CYL:
  281.          _gle_gc -> bgn_gen_texture = bgn_z_texgen;
  282.          _gle_gc -> v3d_gen_texture = normal_cylinder_model_v;
  283.          _gle_gc -> n3d_gen_texture = 0x0;
  284.          break;
  285.       case GLE_TEXTURE_VERTEX_SPH:
  286.          _gle_gc -> bgn_gen_texture = bgn_sphere_texgen;
  287.          _gle_gc -> v3d_gen_texture = vertex_sphere_texgen_v;
  288.          _gle_gc -> n3d_gen_texture = 0x0;
  289.          break;
  290.       case GLE_TEXTURE_NORMAL_SPH:
  291.          _gle_gc -> bgn_gen_texture = bgn_sphere_texgen;
  292.          _gle_gc -> v3d_gen_texture = normal_sphere_texgen_v;
  293.          _gle_gc -> n3d_gen_texture = save_normal;
  294.          break;
  295.       case GLE_TEXTURE_VERTEX_MODEL_SPH:
  296.          _gle_gc -> bgn_gen_texture = bgn_sphere_texgen;
  297.          _gle_gc -> v3d_gen_texture = vertex_sphere_model_v;
  298.          _gle_gc -> n3d_gen_texture = 0x0;
  299.          break;
  300.       case GLE_TEXTURE_NORMAL_MODEL_SPH:
  301.          _gle_gc -> bgn_gen_texture = bgn_sphere_texgen;
  302.          _gle_gc -> v3d_gen_texture = normal_sphere_model_v;
  303.          _gle_gc -> n3d_gen_texture = 0x0;
  304.          break;
  305.       default:
  306.          break;
  307.    }
  308.    /* disable texturing, and save the mode */
  309.    if (!(mode & GLE_TEXTURE_ENABLE)) {
  310.       _gle_gc -> save_bgn_gen_texture = _gle_gc -> bgn_gen_texture; 
  311.       _gle_gc -> save_n3f_gen_texture = _gle_gc -> n3f_gen_texture; 
  312.       _gle_gc -> save_n3d_gen_texture = _gle_gc -> n3d_gen_texture; 
  313.       _gle_gc -> save_v3f_gen_texture = _gle_gc -> v3f_gen_texture; 
  314.       _gle_gc -> save_v3d_gen_texture = _gle_gc -> v3d_gen_texture; 
  315.       _gle_gc -> save_end_gen_texture = _gle_gc -> end_gen_texture; 
  316.       _gle_gc -> bgn_gen_texture = 0x0;
  317.       _gle_gc -> n3f_gen_texture = 0x0;
  318.       _gle_gc -> n3d_gen_texture = 0x0;
  319.       _gle_gc -> v3f_gen_texture = 0x0;
  320.       _gle_gc -> v3d_gen_texture = 0x0;
  321.       _gle_gc -> end_gen_texture = 0x0;
  322.    }
  323. }
  324. /* ================== END OF FILE ========================= */