hufo_fur_texture.cpp
上传用户:yjja2008
上传日期:2022-05-05
资源大小:698k
文件大小:8k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. #include <windows.h>
  2. #include <iostream.h>
  3. #include <nv_util.h>
  4. #include <nv_algebra.h>
  5. #include <GL/gl.h>
  6. #include <GL/glu.h>
  7. #undef GL_GLEXT_PROTOTYPES
  8. #include <GL/glext.h>
  9. // Disable the STL debug information warnings
  10. #pragma warning (disable:4786)
  11. #include <glh_extensions.h>
  12. #include "hufo_fur_setup.h"
  13. inline float rnd(float n)
  14. {
  15.   return (float)rand()*(1.0f/(RAND_MAX+1))*n;
  16. }
  17. GLuint fur_tid[TNLAYER*2];
  18. static void calc_fur();
  19. static void free_fur();
  20. static void upload_fur_color(int layer);
  21. static void upload_fur_normal(int layer);
  22. void hufo_fur_texture_init()
  23. {
  24.   glGenTextures(TNLAYER*2,fur_tid);
  25.   calc_fur();
  26.   for (int i=0;i<TNLAYER;i++)
  27.   {
  28.     glBindTexture(GL_TEXTURE_2D,fur_tid[2*i+0]);
  29.     upload_fur_normal(i);
  30. #if FUR_COLOR_TEXTURE==1
  31.     glBindTexture(GL_TEXTURE_2D,fur_tid[2*i+1]);
  32.     upload_fur_color(i);
  33. #endif
  34.   }
  35.   free_fur();
  36. }
  37. void hufo_fur_texture_use(int layer)
  38. {
  39.   glActiveTextureARB(GL_TEXTURE0_ARB);
  40.   glBindTexture(GL_TEXTURE_2D,fur_tid[2*layer+0]);
  41.   glEnable(GL_TEXTURE_2D);
  42. #if FUR_COLOR_TEXTURE==1
  43.   glActiveTextureARB(GL_TEXTURE1_ARB);
  44.   glBindTexture(GL_TEXTURE_2D,fur_tid[2*layer+1]);
  45.   glEnable(GL_TEXTURE_2D);
  46. #endif
  47. }
  48. void hufo_fur_texture_quit()
  49. {
  50. }
  51. #define TTSIZE 128
  52. #define TTSTEP 1
  53. typedef vec4 NaaColor4f;
  54. typedef vec3 NaaVector3D;
  55. typedef vec3 NaaPoint3D;
  56. class fursample
  57. {
  58. public:
  59.   NaaColor4f c;
  60.   NaaVector3D n;
  61.   fursample() : c(0,0,0,0), n(0,0,0) {}
  62. };
  63. class furdata
  64. {
  65. public:
  66.   fursample grid[TNLAYER][TTSIZE][TTSIZE];
  67.   fursample & operator() (int x,int y,int z)
  68.   {
  69.     static fursample fvoid;
  70.     if ((unsigned) z>=(unsigned)TNLAYER)
  71.       return fvoid;
  72.     return grid[z][y&(TTSIZE-1)][x&(TTSIZE-1)];
  73.   }
  74.   furdata()
  75.   {
  76.     int np=(TTSIZE*TTSIZE)/(3*3);
  77.     for (int i=0;i<np;i++)
  78.     {
  79.       addHair();
  80.     }
  81.     normalize();
  82.   }
  83.   void addSphere(const NaaPoint3D &p,const NaaVector3D &n,const NaaColor4f &c,const NaaVector3D &r)
  84.   { // we need to add a sphere of radius r centered around p with a normal vector n and a color/opacity c
  85.     int x0=int (p.x-r.x) -1;
  86.     int x1=int (p.x+r.x) +2;
  87.     int y0=int (p.y-r.y) -1;
  88.     int y1=int (p.y+r.y) +2;
  89.     int z0=int (p.z-r.z) -1;
  90.     int z1=int (p.z+r.z) +2;
  91.     int x,y,z;
  92.     NaaPoint3D ir(1/r.x,1/r.y,1/r.z);
  93.     NaaPoint3D dp;
  94.     //const float fact=1/(TTSTEP*TTSTEP*TTSTEP);
  95.     for (z=z0,dp.z=(z0-p.z)*ir.z;z<z1;z++,dp.z+=ir.z)
  96.     {
  97.       for (y=y0,dp.y=(y0-p.y)*ir.y;y<y1;y++,dp.y+=ir.y)
  98.       {
  99.         for (x=x0,dp.x=(x0-p.x)*ir.x;x<x1;x++,dp.x+=ir.x)
  100.         {
  101.           // calculate the intersection volume V between the ellipsoid and
  102.           // the cube corresponding to the current point (p2)-(p2+(1,1,1))
  103.           // the transformation to transform the ellipsoid to a sphere
  104.           // of radius 1 centered at the origin is :
  105.           // M=scale(1/r.x,1/r.y,1/r.z).translation(-p)
  106.           //
  107.           //   ( 1/rx 0    0    0 )   ( 1 0 0 -px )
  108.           // M=( 0    1/ry 0    0 ) . ( 0 1 0 -py )
  109.           //   ( 0    0    1/rz 0 )   ( 0 0 1 -pz )
  110.           //   ( 0    0    0    1 )   ( 0 0 0 1   )
  111.           //
  112.           //   ( 1/rx 0    0    -px/rx )
  113.           // M=( 0    1/ry 0    -py/ry )
  114.           //   ( 0    0    1/rz -pz/rz )
  115.           //   ( 0    0    0    1      )
  116.           //
  117.           // the transformed cube c' is them:
  118.           //
  119.           // C'= < M.p2 , m.(p2+(1,1,1)) >
  120.           //
  121.           // the volume of intersection between C' and unit sphere is V'
  122.           //
  123.           // then V = V'*det(M^-1)
  124.           //        = V'*(rx*ry*rz)
  125.           // but the following code is a bad approximation...
  126.           float l=nv_sq_norm(dp);
  127.           if (l<1)
  128.           {
  129.             float fact=1-l;
  130.             fursample& dest=(*this)(x/TTSTEP,y/TTSTEP,z/TTSTEP);
  131.             NaaColor4f c2=c; c2*=fact;
  132.             dest.c+=c2;
  133.             NaaVector3D n2=n; n2*=fact;
  134.             dest.n+=n2;
  135.           }
  136.         }
  137.       }
  138.     }
  139.   }
  140.   void normalize()
  141.   {
  142.     fursample *ptr=&(grid[0][0][0]);
  143.     for (int i=0;i<TNLAYER*TTSIZE*TTSIZE;i++,ptr++)
  144.     {
  145.       if (ptr->c.a>=0.000001f)
  146.       {
  147.         float f=1.0f/ptr->c.a;
  148.         ptr->c.r*=f;
  149.         ptr->c.g*=f;
  150.         ptr->c.b*=f;
  151.         ptr->c.a/=TTSTEP*TTSTEP*TTSTEP;
  152.       }
  153.       else
  154.       {
  155.         ptr->c.r=1;
  156.         ptr->c.g=1;
  157.         ptr->c.b=1;
  158.       }
  159.       ::normalize(ptr->n);
  160.       if (nv_sq_norm(ptr->n)<0.25f)
  161.       {
  162.         ptr->n.x=0;
  163.         ptr->n.y=0;
  164.         ptr->n.z=1;
  165.       }
  166.     }
  167.   }
  168.   void addHair()
  169.   {
  170.     static const NaaColor4f c1(1.0f,1.0f,1.0f,1.0f);
  171.     static const NaaColor4f c2(1.0f,1.0f,1.0f,1.0f);
  172.     NaaPoint3D pos;
  173.     NaaVector3D vel;
  174.     NaaVector3D acc;
  175.     NaaVector3D radius;
  176.     NaaVector3D dr;
  177.     NaaColor4f color;
  178.     int length;
  179.     pos.x=rnd(float(TTSIZE*TTSTEP));
  180.     pos.y=rnd(float(TTSIZE*TTSTEP));
  181.     pos.z=0;
  182.     radius.x=TTSTEP;
  183.     radius.y=TTSTEP;
  184.     radius.z=TTSTEP;
  185.     length=rnd((TNLAYER)*TTSTEP);
  186.     vel.x=rnd(1.0f)-0.5f;
  187.     vel.y=rnd(1.0f)-0.5f;
  188.     vel.z=1;
  189.     acc.x=2*vel.x/length;
  190.     acc.y=2*vel.y/length;
  191.     acc.z=0; //-vel.z/length;
  192.     float f=rnd(1.0f);
  193.     color.r=c1.r*f+c2.r*(1-f);
  194.     color.g=c1.g*f+c2.g*(1-f);
  195.     color.b=c1.b*f+c2.b*(1-f);
  196.     color.a=vel.z/radius.z;
  197.     dr=radius; dr*=(-0.9f/length);
  198.     while (length--)
  199.     {
  200.       addSphere(pos,vel,color,radius);
  201.       pos+=vel;
  202.       vel+=acc;
  203.       radius-=dr;
  204.     }
  205.   }
  206. };
  207. static furdata * cur_fur=NULL;
  208. static void calc_fur()
  209. {
  210.   cur_fur=new furdata();
  211. }
  212. static void upload_fur_color(int layer)
  213. {
  214.   if (cur_fur==NULL) return;
  215.   unsigned char * nmap = new unsigned char[TTSIZE*TTSIZE*4];
  216.   unsigned char * ip = nmap;
  217.   fursample * fp= &(cur_fur->grid[layer][0][0]);
  218.   int i,j;
  219.   for( j = 0; j < TTSIZE; ++j)
  220.   {
  221.     for( i = 0; i < TTSIZE; ++i)
  222.     {
  223.       
  224.       //*ip++ = 0;
  225.       //*ip++ = 200;
  226.       //*ip++ = 255;
  227.       *ip++ = fp->c.r * 255;
  228.       *ip++ = fp->c.g * 255;
  229.       *ip++ = fp->c.b * 255;
  230.       *ip++ = fp->c.a * 255;
  231.       fp++;
  232.     }
  233.   }
  234.   //glTexImage2D(GL_TEXTURE_2D, 0, 4, TTSIZE, TTSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, nmap);
  235.   gluBuild2DMipmaps(GL_TEXTURE_2D, 
  236.     4, 
  237.     TTSIZE,TTSIZE,
  238.     GL_RGBA, 
  239.     GL_UNSIGNED_BYTE, nmap);
  240.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  241.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  242.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  243.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  244.   delete[] nmap;
  245. }
  246. static void upload_fur_normal(int layer)
  247. {
  248.   if (cur_fur==NULL) return;
  249.   unsigned char * nmap = new unsigned char[TTSIZE*TTSIZE*4];
  250.   unsigned char * ip = nmap;
  251.   fursample * fp= &(cur_fur->grid[layer][0][0]);
  252.   int i,j;
  253.   for( j = 0; j < TTSIZE; ++j)
  254.   {
  255.     for( i = 0; i < TTSIZE; ++i)
  256.     {
  257.       
  258.       *ip++ = fp->n.x * 127 + 128;
  259.       *ip++ = fp->n.y * 127 + 128;
  260.       *ip++ = fp->n.z * 127 + 128;
  261.       *ip++ = fp->c.a * 255;
  262.       fp++;
  263.     }
  264.   }
  265.   //glTexImage2D(GL_TEXTURE_2D, 0, 4, TTSIZE, TTSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, nmap);
  266.   gluBuild2DMipmaps(GL_TEXTURE_2D, 
  267.     4, 
  268.     TTSIZE,TTSIZE,
  269.     GL_RGBA, 
  270.     GL_UNSIGNED_BYTE, nmap);
  271.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  272.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  273.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  274.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  275.   delete[] nmap;
  276. }
  277. static void free_fur()
  278. {
  279.   if (cur_fur!=NULL)
  280.   {
  281.     delete cur_fur;
  282.     cur_fur=NULL;
  283.   }
  284. }