📄 flybezier.cpp
字号:
}
if (evaltype&PATCH_EVAL_POINT)
*(dest++)=point;
if (evaltype&PATCH_EVAL_TEXTCOORD)
*(dest++)=textcoord;
if (evaltype&PATCH_EVAL_NORMAL)
{
dest->cross(dv,du);
dest->normalize();
}
}
void bezier_patch::reset()
{
if (p)
delete p;
p=0;
if (t)
delete t;
t=0;
if (surf)
delete surf;
surf=0;
np=npu=npv=nsu=nsv=0;
mode=0;
levelu=0;
levelv=0;
nvertu=0;
nvertv=0;
}
int bezier_patch::load_pch(char *file)
{
reset();
fly_pak fp;
if (!fp.open(file))
return 0;
mode=3;
char texture[256];
fp.get_string(texture);
texpic=flyengine->get_picture(texture);
int lm_pic=fp.get_int();
int lm_offsetx=fp.get_int();
int lm_offsety=fp.get_int();
int lm_sizex=fp.get_int();
int lm_sizey=fp.get_int();
lm=-1;
if (lm_pic<flyengine->nlmpic)
{
flyengine->lm[flyengine->nlm]=new light_map(-1,lm_pic,lm_offsetx,lm_offsety,lm_sizex,lm_sizey,3);
flyengine->fm[flyengine->nlm]=new light_map(-1,lm_pic,lm_offsetx,lm_offsety,lm_sizex,lm_sizey,4);
lm=flyengine->nlm++;
}
npu=fp.get_int();
npv=fp.get_int();
pivot.x=fp.get_float();
pivot.y=fp.get_float();
pivot.z=fp.get_float();
np=npu*npv;
nsu=(npu-1)/2;
nsv=(npv-1)/2;
p=new vector[np];
t=new vector[np];
int i;
for( i=0;i<np;i++ )
{
p[i].x=fp.get_float();
p[i].y=fp.get_float();
p[i].z=fp.get_float();
t[i].x=fp.get_float();
t[i].y=fp.get_float();
t[i].z=fp.get_float();
t[i].w=fp.get_float();
}
fp.close();
return 1;
}
int find_subdiv_level(vector v0,vector v1,vector v2)
{
int level;
vector a, b, dist;
float factor=flyengine->curveerr*flyengine->curveerr;
for (level=0;level<8;level++)
{
a=(v0+v1)*0.5f;
b=(v1+v2)*0.5f;
v2=(a+b)*0.5f;
dist=v2-v1;
if (vec_dot(dist,dist)<factor)
break;
v1=a;
}
return level;
}
void bezier_patch::build_surface()
{
if (mode!=3 || p==0 || t==0)
return;
int i,j,k,a;
vector normal;
levelu=0;
levelv=0;
k=0;
for( j=0;j<=nsv;j++,k+=npu-1 )
for( i=0;i<=nsu;i++,k+=2 )
{
if (i<nsu)
{
a=find_subdiv_level(p[k],p[k+1],p[k+2]);
if (a>levelu)
levelu=a;
}
if (j<nsv)
{
a=find_subdiv_level(p[k],p[k+npu],p[k+2*npu]);
if (a>levelv)
levelv=a;
}
}
nvertu=(1<<levelu)*nsu+1;
nvertv=(1<<levelv)*nsv+1;
if (nvertu<2) nvertu=2;
if (nvertv<2) nvertv=2;
if (surf) delete surf;
surf=new vector[nvertu*nvertv*2];
k=0;
for( j=0;j<nvertv;j++ )
for( i=0;i<nvertu;i++,k+=2 )
evaluate(PATCH_EVAL_POINT|PATCH_EVAL_TEXTCOORD,
(float)i/(nvertu-1),(float)j/(nvertv-1),&surf[k]);
}
void bezier_patch::illuminate(vector& p,float rad,vector& color,int shadows)
{
if (lm==-1)
return;
int i,j,k;
float dist,u,v;
vector point,dir;
// get lightmap applied to patch
light_map *l=flyengine->lm[lm];
unsigned char *uc;
rad*=rad;
// for each lightmap pixel in y
for( j=0;j<l->sizey;j++ )
{
uc=&l->bmp[j*l->bytesx];
v=(j+0.5f)/l->sizey;
// for each lightmap pixel in x
for( i=0;i<l->sizex;i++ )
{
u=(i+0.5f)/l->sizex;
// get lightmap pixel position in the patch surface
evaluate(PATCH_EVAL_POINT,u,v,&point);
// check if point is inside light radius
dir=p-point;
dist=vec_dot(dir,dir);
if (dist>rad)
uc+=3;
else
{
// compute lighting factor based on light radius and pixel distance
dist=(1.0f-dist/rad)*255.0f;
// apply colors to lightmap
k=(int)(color.x*dist)+(int)(*uc);
*(uc++)=k>255?255:k;
k=(int)(color.y*dist)+(int)(*uc);
*(uc++)=k>255?255:k;
k=(int)(color.z*dist)+(int)(*uc);
*(uc++)=k>255?255:k;
}
}
}
l->lastupdate=flyengine->cur_step;
}
void bezier_patch::draw(int nleveldrop)
{
if (surf==0)
return;
int i,j,k,l,mapcount=0;
float *f1,*f2;
int dropu,dropv,numstrips;
if (levelu>=nleveldrop)
dropu=nleveldrop;
else dropu=levelu;
if (levelv>=nleveldrop)
dropv=nleveldrop;
else dropv=levelv;
numstrips=(1<<(levelv-dropv))*nsv;
dropu=(1<<dropu);
dropv=(1<<dropv);
k=dropu*8;
l=dropv*nvertu*2;
glColor3ub(255,255,255);
if (flyengine->multitexture && ntextureunits>1 && flyengine->nlm)
{
tc->use(texpic);
if (lm!=-1)
tc->use(flyengine->lm[lm]->pic+flyengine->lmbase,1);
for( j=0;j<numstrips;j++ )
{
f1=(float * )&surf[j*l]; f2=f1+(l<<2);
glBegin(GL_TRIANGLE_STRIP);
for( i=0;i<nvertu;i+=dropu,f1+=k,f2+=k)
{
glMultiTexCoord2fvARB(GL_TEXTURE0_ARB,f2+4);
glMultiTexCoord2fvARB(GL_TEXTURE1_ARB,f2+6);
glVertex3fv(f2);
glMultiTexCoord2fvARB(GL_TEXTURE0_ARB,f1+4);
glMultiTexCoord2fvARB(GL_TEXTURE1_ARB,f1+6);
glVertex3fv(f1);
}
glEnd();
}
tc->use(-1,1);
tc->use(-1,0);
mapcount+=2;
}
else
{
if (flyengine->mapmode&MAPPING_TEXTURE)
{
tc->use(texpic);
for( j=0;j<numstrips;j++ )
{
f1=(float * )&surf[j*l]; f2=f1+(l<<2);
glBegin(GL_TRIANGLE_STRIP);
for( i=0;i<nvertu;i+=dropu,f1+=k,f2+=k)
{
glTexCoord2fv(f2+4);
glVertex3fv(f2);
glTexCoord2fv(f1+4);
glVertex3fv(f1);
}
glEnd();
}
mapcount++;
}
if (flyengine->mapmode&MAPPING_DETAIL &&
flyengine->detailpic!=-1)
{
if (mapcount)
{
glBlendFunc(GL_ZERO,GL_SRC_COLOR);
glDepthMask(GL_FALSE);
glDepthFunc(GL_EQUAL);
}
tc->use(flyengine->detailpic);
for( j=0;j<numstrips;j++ )
{
f1=(float * )&surf[j*l]; f2=f1+(l<<2);
glBegin(GL_TRIANGLE_STRIP);
for( i=0;i<nvertu;i+=dropu,f1+=k,f2+=k)
{
glTexCoord2f(f2[4]*flyengine->detailtile,f2[5]*flyengine->detailtile);
glVertex3fv(f2);
glTexCoord2f(f1[4]*flyengine->detailtile,f1[5]*flyengine->detailtile);
glVertex3fv(f1);
}
glEnd();
}
mapcount++;
}
if (flyengine->mapmode&MAPPING_LIGHTMAP &&
flyengine->nlm!=0)
{
if (mapcount)
{
glBlendFunc(GL_ZERO,GL_SRC_COLOR);
glDepthMask(GL_FALSE);
glDepthFunc(GL_EQUAL);
}
tc->use(flyengine->lm[lm]->pic+flyengine->lmbase);
for( j=0;j<numstrips;j++ )
{
f1=(float * )&surf[j*l]; f2=f1+(l<<2);
glBegin(GL_TRIANGLE_STRIP);
for( i=0;i<nvertu;i+=dropu,f1+=k,f2+=k)
{
glTexCoord2fv(f2+6);
glVertex3fv(f2);
glTexCoord2fv(f1+6);
glVertex3fv(f1);
}
glEnd();
}
mapcount++;
}
}
if (flyengine->mapmode&MAPPING_FOGMAP)
if (flyengine->nlm!=0)
{
if (mapcount)
{
glDepthMask(GL_FALSE);
glDepthFunc(GL_EQUAL);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
}
tc->use(flyengine->lm[lm]->pic+flyengine->fmbase);
for( j=0;j<numstrips;j++ )
{
f1=(float * )&surf[j*l]; f2=f1+(l<<2);
glBegin(GL_TRIANGLE_STRIP);
for( i=0;i<nvertu;i+=dropu,f1+=k,f2+=k)
{
glTexCoord2fv(f2+6);
glVertex3fv(f2);
glTexCoord2fv(f1+6);
glVertex3fv(f1);
}
glEnd();
}
mapcount++;
}
glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
mesh *bezier_patch::build_mesh()
{
int i,j,k;
mesh *m=new mesh;
m->nv=nvertu*nvertv;
m->vert=new vector[m->nv];
k=0;
for( i=0;i<m->nv;i++,k+=2 )
m->vert[i]=surf[k];
m->nf=(nvertu-1)*(nvertv-1)*2;
m->localfaces=new face[m->nf];
m->faces=new face *[m->nf];
k=0;
for( j=0;j<nvertv-1;j++ )
for( i=0;i<nvertu-1;i++ )
{
m->localfaces[k].color.vec(1,1,1,1);
m->localfaces[k].vert[0]=&m->vert[j*nvertu+i];
m->localfaces[k].vert[1]=&m->vert[j*nvertu+i+1];
m->localfaces[k].vert[2]=&m->vert[(j+1)*nvertu+i+1];
m->faces[k]=&m->localfaces[k];
k++;
m->localfaces[k].color.vec(1,1,1,1);
m->localfaces[k].vert[0]=&m->vert[j*nvertu+i];
m->localfaces[k].vert[1]=&m->vert[(j+1)*nvertu+i+1];
m->localfaces[k].vert[2]=&m->vert[(j+1)*nvertu+i];
m->faces[k]=&m->localfaces[k];
k++;
}
m->compute_normals(MESH_FACENORM|MESH_VERTNORM|MESH_BBOX);
return m;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -