hufo_fur_texture.cpp
资源名称:fur.zip [点击查看]
上传用户:yjja2008
上传日期:2022-05-05
资源大小:698k
文件大小:8k
源码类别:
3D图形编程
开发平台:
Visual C++
- #include <windows.h>
- #include <iostream.h>
- #include <nv_util.h>
- #include <nv_algebra.h>
- #include <GL/gl.h>
- #include <GL/glu.h>
- #undef GL_GLEXT_PROTOTYPES
- #include <GL/glext.h>
- // Disable the STL debug information warnings
- #pragma warning (disable:4786)
- #include <glh_extensions.h>
- #include "hufo_fur_setup.h"
- inline float rnd(float n)
- {
- return (float)rand()*(1.0f/(RAND_MAX+1))*n;
- }
- GLuint fur_tid[TNLAYER*2];
- static void calc_fur();
- static void free_fur();
- static void upload_fur_color(int layer);
- static void upload_fur_normal(int layer);
- void hufo_fur_texture_init()
- {
- glGenTextures(TNLAYER*2,fur_tid);
- calc_fur();
- for (int i=0;i<TNLAYER;i++)
- {
- glBindTexture(GL_TEXTURE_2D,fur_tid[2*i+0]);
- upload_fur_normal(i);
- #if FUR_COLOR_TEXTURE==1
- glBindTexture(GL_TEXTURE_2D,fur_tid[2*i+1]);
- upload_fur_color(i);
- #endif
- }
- free_fur();
- }
- void hufo_fur_texture_use(int layer)
- {
- glActiveTextureARB(GL_TEXTURE0_ARB);
- glBindTexture(GL_TEXTURE_2D,fur_tid[2*layer+0]);
- glEnable(GL_TEXTURE_2D);
- #if FUR_COLOR_TEXTURE==1
- glActiveTextureARB(GL_TEXTURE1_ARB);
- glBindTexture(GL_TEXTURE_2D,fur_tid[2*layer+1]);
- glEnable(GL_TEXTURE_2D);
- #endif
- }
- void hufo_fur_texture_quit()
- {
- }
- #define TTSIZE 128
- #define TTSTEP 1
- typedef vec4 NaaColor4f;
- typedef vec3 NaaVector3D;
- typedef vec3 NaaPoint3D;
- class fursample
- {
- public:
- NaaColor4f c;
- NaaVector3D n;
- fursample() : c(0,0,0,0), n(0,0,0) {}
- };
- class furdata
- {
- public:
- fursample grid[TNLAYER][TTSIZE][TTSIZE];
- fursample & operator() (int x,int y,int z)
- {
- static fursample fvoid;
- if ((unsigned) z>=(unsigned)TNLAYER)
- return fvoid;
- return grid[z][y&(TTSIZE-1)][x&(TTSIZE-1)];
- }
- furdata()
- {
- int np=(TTSIZE*TTSIZE)/(3*3);
- for (int i=0;i<np;i++)
- {
- addHair();
- }
- normalize();
- }
- void addSphere(const NaaPoint3D &p,const NaaVector3D &n,const NaaColor4f &c,const NaaVector3D &r)
- { // we need to add a sphere of radius r centered around p with a normal vector n and a color/opacity c
- int x0=int (p.x-r.x) -1;
- int x1=int (p.x+r.x) +2;
- int y0=int (p.y-r.y) -1;
- int y1=int (p.y+r.y) +2;
- int z0=int (p.z-r.z) -1;
- int z1=int (p.z+r.z) +2;
- int x,y,z;
- NaaPoint3D ir(1/r.x,1/r.y,1/r.z);
- NaaPoint3D dp;
- //const float fact=1/(TTSTEP*TTSTEP*TTSTEP);
- for (z=z0,dp.z=(z0-p.z)*ir.z;z<z1;z++,dp.z+=ir.z)
- {
- for (y=y0,dp.y=(y0-p.y)*ir.y;y<y1;y++,dp.y+=ir.y)
- {
- for (x=x0,dp.x=(x0-p.x)*ir.x;x<x1;x++,dp.x+=ir.x)
- {
- // calculate the intersection volume V between the ellipsoid and
- // the cube corresponding to the current point (p2)-(p2+(1,1,1))
- // the transformation to transform the ellipsoid to a sphere
- // of radius 1 centered at the origin is :
- // M=scale(1/r.x,1/r.y,1/r.z).translation(-p)
- //
- // ( 1/rx 0 0 0 ) ( 1 0 0 -px )
- // M=( 0 1/ry 0 0 ) . ( 0 1 0 -py )
- // ( 0 0 1/rz 0 ) ( 0 0 1 -pz )
- // ( 0 0 0 1 ) ( 0 0 0 1 )
- //
- // ( 1/rx 0 0 -px/rx )
- // M=( 0 1/ry 0 -py/ry )
- // ( 0 0 1/rz -pz/rz )
- // ( 0 0 0 1 )
- //
- // the transformed cube c' is them:
- //
- // C'= < M.p2 , m.(p2+(1,1,1)) >
- //
- // the volume of intersection between C' and unit sphere is V'
- //
- // then V = V'*det(M^-1)
- // = V'*(rx*ry*rz)
- // but the following code is a bad approximation...
- float l=nv_sq_norm(dp);
- if (l<1)
- {
- float fact=1-l;
- fursample& dest=(*this)(x/TTSTEP,y/TTSTEP,z/TTSTEP);
- NaaColor4f c2=c; c2*=fact;
- dest.c+=c2;
- NaaVector3D n2=n; n2*=fact;
- dest.n+=n2;
- }
- }
- }
- }
- }
- void normalize()
- {
- fursample *ptr=&(grid[0][0][0]);
- for (int i=0;i<TNLAYER*TTSIZE*TTSIZE;i++,ptr++)
- {
- if (ptr->c.a>=0.000001f)
- {
- float f=1.0f/ptr->c.a;
- ptr->c.r*=f;
- ptr->c.g*=f;
- ptr->c.b*=f;
- ptr->c.a/=TTSTEP*TTSTEP*TTSTEP;
- }
- else
- {
- ptr->c.r=1;
- ptr->c.g=1;
- ptr->c.b=1;
- }
- ::normalize(ptr->n);
- if (nv_sq_norm(ptr->n)<0.25f)
- {
- ptr->n.x=0;
- ptr->n.y=0;
- ptr->n.z=1;
- }
- }
- }
- void addHair()
- {
- static const NaaColor4f c1(1.0f,1.0f,1.0f,1.0f);
- static const NaaColor4f c2(1.0f,1.0f,1.0f,1.0f);
- NaaPoint3D pos;
- NaaVector3D vel;
- NaaVector3D acc;
- NaaVector3D radius;
- NaaVector3D dr;
- NaaColor4f color;
- int length;
- pos.x=rnd(float(TTSIZE*TTSTEP));
- pos.y=rnd(float(TTSIZE*TTSTEP));
- pos.z=0;
- radius.x=TTSTEP;
- radius.y=TTSTEP;
- radius.z=TTSTEP;
- length=rnd((TNLAYER)*TTSTEP);
- vel.x=rnd(1.0f)-0.5f;
- vel.y=rnd(1.0f)-0.5f;
- vel.z=1;
- acc.x=2*vel.x/length;
- acc.y=2*vel.y/length;
- acc.z=0; //-vel.z/length;
- float f=rnd(1.0f);
- color.r=c1.r*f+c2.r*(1-f);
- color.g=c1.g*f+c2.g*(1-f);
- color.b=c1.b*f+c2.b*(1-f);
- color.a=vel.z/radius.z;
- dr=radius; dr*=(-0.9f/length);
- while (length--)
- {
- addSphere(pos,vel,color,radius);
- pos+=vel;
- vel+=acc;
- radius-=dr;
- }
- }
- };
- static furdata * cur_fur=NULL;
- static void calc_fur()
- {
- cur_fur=new furdata();
- }
- static void upload_fur_color(int layer)
- {
- if (cur_fur==NULL) return;
- unsigned char * nmap = new unsigned char[TTSIZE*TTSIZE*4];
- unsigned char * ip = nmap;
- fursample * fp= &(cur_fur->grid[layer][0][0]);
- int i,j;
- for( j = 0; j < TTSIZE; ++j)
- {
- for( i = 0; i < TTSIZE; ++i)
- {
- //*ip++ = 0;
- //*ip++ = 200;
- //*ip++ = 255;
- *ip++ = fp->c.r * 255;
- *ip++ = fp->c.g * 255;
- *ip++ = fp->c.b * 255;
- *ip++ = fp->c.a * 255;
- fp++;
- }
- }
- //glTexImage2D(GL_TEXTURE_2D, 0, 4, TTSIZE, TTSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, nmap);
- gluBuild2DMipmaps(GL_TEXTURE_2D,
- 4,
- TTSIZE,TTSIZE,
- GL_RGBA,
- GL_UNSIGNED_BYTE, nmap);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- delete[] nmap;
- }
- static void upload_fur_normal(int layer)
- {
- if (cur_fur==NULL) return;
- unsigned char * nmap = new unsigned char[TTSIZE*TTSIZE*4];
- unsigned char * ip = nmap;
- fursample * fp= &(cur_fur->grid[layer][0][0]);
- int i,j;
- for( j = 0; j < TTSIZE; ++j)
- {
- for( i = 0; i < TTSIZE; ++i)
- {
- *ip++ = fp->n.x * 127 + 128;
- *ip++ = fp->n.y * 127 + 128;
- *ip++ = fp->n.z * 127 + 128;
- *ip++ = fp->c.a * 255;
- fp++;
- }
- }
- //glTexImage2D(GL_TEXTURE_2D, 0, 4, TTSIZE, TTSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, nmap);
- gluBuild2DMipmaps(GL_TEXTURE_2D,
- 4,
- TTSIZE,TTSIZE,
- GL_RGBA,
- GL_UNSIGNED_BYTE, nmap);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- delete[] nmap;
- }
- static void free_fur()
- {
- if (cur_fur!=NULL)
- {
- delete cur_fur;
- cur_fur=NULL;
- }
- }