advtreedrawer.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 893 行 · 第 1/3 页
CPP
893 行
// draw far away trees using the map dependent grid visibility
oldTreeDistance=treeDistance;
readmap->GridVisibility (camera, TREE_SQUARE_SIZE, treeDistance*2*SQUARE_SIZE*TREE_SQUARE_SIZE, &drawer);
if(drawDetailed){
if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeVP );
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);
glActiveTextureARB(GL_TEXTURE0_ARB);
} else {
glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeNSVP );
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,15, 1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),1.0f/(gs->pwr2mapx*SQUARE_SIZE),1);
}
glEnable( GL_VERTEX_PROGRAM_ARB );
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, camera->right.x,camera->right.y,camera->right.z,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9, camera->up.x,camera->up.y,camera->up.z,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11, readmap->sunColor.x,readmap->sunColor.y,readmap->sunColor.z,0.85f);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,14, readmap->ambientColor.x,readmap->ambientColor.y,readmap->ambientColor.z,0.85f);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, 0,0,0,0.20f*(1.0f/MAX_TREE_HEIGHT)); //w=alpha/height modifier
glAlphaFunc(GL_GREATER,0.5f);
glDisable(GL_BLEND);
glColor4f(1,1,1,1);
va=GetVertexArray();
va->Initialize();
struct FadeTree{
float3 pos;
float relDist;
float deltaY;
int type;
};
static FadeTree fadeTrees[3000];
int curFade=0;
for(int y=max(0,cy-2);y<=min(gs->mapy/TREE_SQUARE_SIZE-1,cy+2);++y){ //close trees
for(int x=max(0,cx-2);x<=min(gs->mapx/TREE_SQUARE_SIZE-1,cx+2);++x){
TreeSquareStruct* tss=&trees[y*treesX+x];
tss->lastSeen=gs->frameNum;
for(std::map<int,TreeStruct>::iterator ti=tss->trees.begin();ti!=tss->trees.end();++ti){
TreeStruct* ts=&ti->second;
float3 pos(ts->pos);
int type=ts->type;
float dy;
unsigned int displist;
if(type<8){
dy=0.5f;
displist=treeGen->pineDL+type;
} else {
type-=8;
dy=0;
displist=treeGen->leafDL+type;
}
if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){
float camDist=(pos-camera->pos).SqLength();
if(camDist<SQUARE_SIZE*SQUARE_SIZE*110*110){ //draw detailed tree
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0);
glCallList(displist);
} else if(camDist<SQUARE_SIZE*SQUARE_SIZE*125*125){ //draw fading tree
float relDist=(pos.distance(camera->pos)-SQUARE_SIZE*110)/(SQUARE_SIZE*15);
glAlphaFunc(GL_GREATER,0.8f+relDist*0.2f);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0);
glCallList(displist);
glAlphaFunc(GL_GREATER,0.5f);
fadeTrees[curFade].pos=pos;
fadeTrees[curFade].deltaY=dy;
fadeTrees[curFade].type=type;
fadeTrees[curFade++].relDist=relDist;
} else { //draw undetailed tree
float height=MAX_TREE_HEIGHT;
float width=MAX_TREE_HEIGHT*0.5f;
float xdif=type*0.125f;
SetArray(TEX_LEAF_START_X1+xdif,TEX_LEAF_START_Y1+dy,pos+float3(width,0,0));
SetArray(TEX_LEAF_START_X1+xdif,TEX_LEAF_END_Y1+dy,pos+float3(width,height,0));
SetArray(TEX_LEAF_END_X1+xdif,TEX_LEAF_END_Y1+dy,pos+float3(-width,height,0));
SetArray(TEX_LEAF_END_X1+xdif,TEX_LEAF_START_Y1+dy,pos+float3(-width,0,0));
SetArray(TEX_LEAF_START_X2+xdif,TEX_LEAF_START_Y2+dy,pos+float3(0,0,width));
SetArray(TEX_LEAF_START_X2+xdif,TEX_LEAF_END_Y2+dy,pos+float3(0,height,width));
SetArray(TEX_LEAF_END_X2+xdif,TEX_LEAF_END_Y2+dy,pos+float3(0,height,-width));
SetArray(TEX_LEAF_END_X2+xdif,TEX_LEAF_START_Y2+dy,pos+float3(0,0,-width));
//width*=1.41f;
SetArray(TEX_LEAF_START_X3+xdif,TEX_LEAF_START_Y3+dy,pos+float3(width,height*0.4f,width));
SetArray(TEX_LEAF_START_X3+xdif,TEX_LEAF_END_Y3+dy,pos+float3(width,height*0.4f,-width));
SetArray(TEX_LEAF_END_X3+xdif,TEX_LEAF_END_Y3+dy,pos+float3(-width,height*0.4f,-width));
SetArray(TEX_LEAF_END_X3+xdif,TEX_LEAF_START_Y3+dy,pos+float3(-width,height*0.4f,width));
}
}
}
}
//draw trees that has been marked as falling
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,0,0,0,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, camera->right.x,camera->right.y,camera->right.z,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9, camera->up.x,camera->up.y,camera->up.z,0);
for(std::list<FallingTree>::iterator fti=fallingTrees.begin();fti!=fallingTrees.end();){
float3 pos=fti->pos-UpVector*(fti->fallPos*20);
if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){
float ang=fti->fallPos*PI;
float3 up(fti->dir.x*sin(ang),cos(ang),fti->dir.z*sin(ang));
float3 z(up.cross(float3(-1,0,0)));
z.Normalize();
float3 x(up.cross(z));
CMatrix44f transMatrix(pos,x,up,z);
glPushMatrix();
glMultMatrixf(&transMatrix[0]);
int type=fti->type;
int displist;
if(type<8){
displist=treeGen->pineDL+type;
} else {
type-=8;
displist=treeGen->leafDL+type;
}
glCallList(displist);
glPopMatrix();
}
++fti;
}
}
glDisable( GL_VERTEX_PROGRAM_ARB );
if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarVP );
glEnable(GL_VERTEX_PROGRAM_ARB);
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, activeFarTex);
glActiveTextureARB(GL_TEXTURE0_ARB);
} else {
glBindTexture(GL_TEXTURE_2D, activeFarTex);
}
va->DrawArrayT(GL_QUADS);
for(int a=0;a<curFade;++a){ //faded close trees
va=GetVertexArray();
va->Initialize();
int type=fadeTrees[a].type;
float dy=fadeTrees[a].deltaY;
float height=MAX_TREE_HEIGHT;
float width=MAX_TREE_HEIGHT*0.5f;
float xdif=type*0.125f;
SetArray(TEX_LEAF_START_X1+xdif,TEX_LEAF_START_Y1+dy,fadeTrees[a].pos+float3(width,0,0));
SetArray(TEX_LEAF_START_X1+xdif,TEX_LEAF_END_Y1+dy,fadeTrees[a].pos+float3(width,height,0));
SetArray(TEX_LEAF_END_X1+xdif,TEX_LEAF_END_Y1+dy,fadeTrees[a].pos+float3(-width,height,0));
SetArray(TEX_LEAF_END_X1+xdif,TEX_LEAF_START_Y1+dy,fadeTrees[a].pos+float3(-width,0,0));
SetArray(TEX_LEAF_START_X2+xdif,TEX_LEAF_START_Y2+dy,fadeTrees[a].pos+float3(0,0,width));
SetArray(TEX_LEAF_START_X2+xdif,TEX_LEAF_END_Y2+dy,fadeTrees[a].pos+float3(0,height,width));
SetArray(TEX_LEAF_END_X2+xdif,TEX_LEAF_END_Y2+dy,fadeTrees[a].pos+float3(0,height,-width));
SetArray(TEX_LEAF_END_X2+xdif,TEX_LEAF_START_Y2+dy,fadeTrees[a].pos+float3(0,0,-width));
//width*=1.41f;
SetArray(TEX_LEAF_START_X3+xdif,TEX_LEAF_START_Y3+dy,fadeTrees[a].pos+float3(width,height*0.4f,width));
SetArray(TEX_LEAF_START_X3+xdif,TEX_LEAF_END_Y3+dy,fadeTrees[a].pos+float3(width,height*0.4f,-width));
SetArray(TEX_LEAF_END_X3+xdif,TEX_LEAF_END_Y3+dy,fadeTrees[a].pos+float3(-width,height*0.4f,-width));
SetArray(TEX_LEAF_END_X3+xdif,TEX_LEAF_START_Y3+dy,fadeTrees[a].pos+float3(-width,height*0.4f,width));
glAlphaFunc(GL_GREATER,1-fadeTrees[a].relDist*0.5f);
va->DrawArrayT(GL_QUADS);
}
}
if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
glDisable( GL_VERTEX_PROGRAM_ARB );
if(shadowHandler->useFPShadows){
glDisable(GL_FRAGMENT_PROGRAM_ARB);
}
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
}
glDisable(GL_ALPHA_TEST);
//clean out squares from memory that are no longer visible
int startClean=lastListClean*20%(treesX*treesY);
lastListClean=gs->frameNum;
int endClean=gs->frameNum*20%(treesX*treesY);
if(startClean>endClean){
for(int a=startClean;a<treesX*treesY;a++){
if(trees[a].lastSeen<gs->frameNum-50 && trees[a].displist){
glDeleteLists(trees[a].displist,1);
trees[a].displist=0;
}
if(trees[a].lastSeenFar<gs->frameNum-50 && trees[a].farDisplist){
glDeleteLists(trees[a].farDisplist,1);
trees[a].farDisplist=0;
}
}
for(int a=0;a<endClean;a++){
if(trees[a].lastSeen<gs->frameNum-50 && trees[a].displist){
glDeleteLists(trees[a].displist,1);
trees[a].displist=0;
}
if(trees[a].lastSeenFar<gs->frameNum-50 && trees[a].farDisplist){
glDeleteLists(trees[a].farDisplist,1);
trees[a].farDisplist=0;
}
}
} else {
for(int a=startClean;a<endClean;a++){
if(trees[a].lastSeen<gs->frameNum-50 && trees[a].displist){
glDeleteLists(trees[a].displist,1);
trees[a].displist=0;
}
if(trees[a].lastSeenFar<gs->frameNum-50 && trees[a].farDisplist){
glDeleteLists(trees[a].farDisplist,1);
trees[a].farDisplist=0;
}
}
}
}
struct CAdvTreeSquareDrawer_SP : CReadMap::IQuadDrawer
{
void DrawQuad (int x,int y);
CAdvTreeDrawer *td;
int cx,cy;
bool drawDetailed;
float treeDistance;
};
void CAdvTreeSquareDrawer_SP::DrawQuad (int x,int y)
{
CAdvTreeDrawer::TreeSquareStruct* tss=&td->trees[y*td->treesX+x];
if(abs(cy-y)<=2 && abs(cx-x)<=2 && drawDetailed) //skip the closest squares
return;
float3 dif;
dif.x=camera->pos.x-(x*SQUARE_SIZE*TREE_SQUARE_SIZE + SQUARE_SIZE*TREE_SQUARE_SIZE/2);
dif.y=0;
dif.z=camera->pos.z-(y*SQUARE_SIZE*TREE_SQUARE_SIZE + SQUARE_SIZE*TREE_SQUARE_SIZE/2);
float dist=dif.Length();
dif/=dist;
if(dist<SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2 && dist>SQUARE_SIZE*TREE_SQUARE_SIZE*(treeDistance)){//far trees
tss->lastSeenFar=gs->frameNum;
if(!tss->farDisplist || dif.dot(tss->viewVector)<0.97f){
va=GetVertexArray();
va->Initialize();
tss->viewVector=dif;
if(!tss->farDisplist)
tss->farDisplist=glGenLists(1);
float3 up(0,1,0);
float3 side=up.cross(dif);
for(std::map<int,CAdvTreeDrawer::TreeStruct>::iterator ti=tss->trees.begin();ti!=tss->trees.end();++ti){
CAdvTreeDrawer::TreeStruct* ts=&ti->second;
float3 base(ts->pos);
int type=ts->type;
float height=MAX_TREE_HEIGHT;
float width=MAX_TREE_HEIGHT*0.5f;
float xdif;
float ydif;
if(ts->type<8){
xdif=type*0.125f;
ydif=0.5f;
} else {
xdif=(type-8)*0.125f;
ydif=0;
}
SetArray(TEX_LEAF_START_X1+xdif,TEX_LEAF_START_Y4+ydif,base+side*width);
SetArray(TEX_LEAF_START_X1+xdif,TEX_LEAF_END_Y4+ydif ,base+side*width+float3(0,height,0));
SetArray(TEX_LEAF_END_X1+xdif ,TEX_LEAF_END_Y4+ydif ,base-side*width+float3(0,height,0));
SetArray(TEX_LEAF_END_X1+xdif ,TEX_LEAF_START_Y4+ydif,base-side*width);
}
glNewList(td->trees[y*td->treesX+x].farDisplist,GL_COMPILE);
va->DrawArrayT(GL_QUADS);
glEndList();
}
if(dist>SQUARE_SIZE*TREE_SQUARE_SIZE*(treeDistance*2-1)){
float trans=(SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2-dist)/(SQUARE_SIZE*TREE_SQUARE_SIZE);
glColor4f(1,1,1,trans);
glAlphaFunc(GL_GREATER,(SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance*2-dist)/(SQUARE_SIZE*TREE_SQUARE_SIZE*2));
} else {
glColor4f(1,1,1,1);
glAlphaFunc(GL_GREATER,0.5f);
}
glCallList(tss->farDisplist);
}
if(dist<SQUARE_SIZE*TREE_SQUARE_SIZE*treeDistance){ //midle distance trees
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?