advtreedrawer.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 893 行 · 第 1/3 页
CPP
893 行
tss->lastSeen=gs->frameNum;
if(!tss->displist){
va=GetVertexArray();
va->Initialize();
tss->displist=glGenLists(1);
for(std::map<int,CAdvTreeDrawer::TreeStruct>::iterator ti=tss->trees.begin();ti!=tss->trees.end();++ti){
CAdvTreeDrawer::TreeStruct* ts=&ti->second;
float3 pos(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_Y1+ydif,pos+float3(width,0,0));
SetArray(TEX_LEAF_START_X1+xdif,TEX_LEAF_END_Y1+ydif,pos+float3(width,height,0));
SetArray(TEX_LEAF_END_X1+xdif,TEX_LEAF_END_Y1+ydif,pos+float3(-width,height,0));
SetArray(TEX_LEAF_END_X1+xdif,TEX_LEAF_START_Y1+ydif,pos+float3(-width,0,0));
SetArray(TEX_LEAF_START_X2+xdif,TEX_LEAF_START_Y2+ydif,pos+float3(0,0,width));
SetArray(TEX_LEAF_START_X2+xdif,TEX_LEAF_END_Y2+ydif,pos+float3(0,height,width));
SetArray(TEX_LEAF_END_X2+xdif,TEX_LEAF_END_Y2+ydif,pos+float3(0,height,-width));
SetArray(TEX_LEAF_END_X2+xdif,TEX_LEAF_START_Y2+ydif,pos+float3(0,0,-width));
//width*=1.41f;
SetArray(TEX_LEAF_START_X3+xdif,TEX_LEAF_START_Y3+ydif,pos+float3(width,height*0.4f,0));
SetArray(TEX_LEAF_START_X3+xdif,TEX_LEAF_END_Y3+ydif,pos+float3(0,height*0.4f,-width));
SetArray(TEX_LEAF_END_X3+xdif,TEX_LEAF_END_Y3+ydif,pos+float3(-width,height*0.4f,0));
SetArray(TEX_LEAF_END_X3+xdif,TEX_LEAF_START_Y3+ydif,pos+float3(0,height*0.4f,width));
}
glNewList(tss->displist,GL_COMPILE);
va->DrawArrayT(GL_QUADS);
glEndList();
}
glColor4f(1,1,1,1);
glAlphaFunc(GL_GREATER,0.5f);
glCallList(tss->displist);
}
}
void CAdvTreeDrawer::DrawShadowPass(void)
{
float treeDistance=oldTreeDistance;
int activeFarTex=camera->forward.z<0 ? treeGen->farTex[0] : treeGen->farTex[1];
bool drawDetailed=true;
if(treeDistance<4)
drawDetailed=false;
glBindTexture(GL_TEXTURE_2D, activeFarTex);
glEnable(GL_TEXTURE_2D);
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarShadowVP );
glEnable( GL_VERTEX_PROGRAM_ARB );
glEnable(GL_ALPHA_TEST);
glPolygonOffset(1,1);
glEnable(GL_POLYGON_OFFSET_FILL);
CAdvTreeSquareDrawer_SP drawer;
int cx = drawer.cx=(int)(camera->pos.x/(SQUARE_SIZE*TREE_SQUARE_SIZE));
int cy = drawer.cy=(int)(camera->pos.z/(SQUARE_SIZE*TREE_SQUARE_SIZE));
drawer.drawDetailed = drawDetailed;
drawer.td = this;
drawer.treeDistance = treeDistance;
// draw with extraSize=1
readmap->GridVisibility (camera, TREE_SQUARE_SIZE, treeDistance*2*SQUARE_SIZE*TREE_SQUARE_SIZE, &drawer, 1);
if(drawDetailed){
glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);
glEnable(GL_TEXTURE_2D);
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeShadowVP );
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, 1,1,1,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);
glEnable(GL_ALPHA_TEST);
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=std::max(0,cy-2);y<=std::min(gs->mapy/TREE_SQUARE_SIZE-1,cy+2);++y){ //close trees
for(int x=std::max(0,cx-2);x<=std::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+150)){
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 have been marked as falling
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,0,0,0,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(z.cross(up));
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;
}
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarShadowVP );
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);
}
}
glDisable(GL_POLYGON_OFFSET_FILL);
glDisable( GL_VERTEX_PROGRAM_ARB );
glDisable(GL_TEXTURE_2D);
glDisable(GL_ALPHA_TEST);
}
void CAdvTreeDrawer::DrawGrass(void)
{
grassDrawer->Draw();
}
void CAdvTreeDrawer::ResetPos(const float3& pos)
{
int x=(int)pos.x/TREE_SQUARE_SIZE/SQUARE_SIZE;
int y=(int)pos.z/TREE_SQUARE_SIZE/SQUARE_SIZE;
int a=y*treesX+x;
if(trees[a].displist){
glDeleteLists(trees[a].displist,1);
trees[a].displist=0;
}
if(trees[a].farDisplist){
glDeleteLists(trees[a].farDisplist,1);
trees[a].farDisplist=0;
}
grassDrawer->ResetPos(pos);
}
void CAdvTreeDrawer::AddTree(int type, float3 pos, float size)
{
TreeStruct ts;
ts.pos=pos;
ts.type=type;
int hash=(int)pos.x+((int)(pos.z))*20000;
int square=((int)pos.x)/(SQUARE_SIZE*TREE_SQUARE_SIZE)+((int)pos.z)/(SQUARE_SIZE*TREE_SQUARE_SIZE)*treesX;
trees[square].trees[hash]=ts;
ResetPos(pos);
}
void CAdvTreeDrawer::DeleteTree(float3 pos)
{
int hash=(int)pos.x+((int)(pos.z))*20000;
int square=((int)pos.x)/(SQUARE_SIZE*TREE_SQUARE_SIZE)+((int)pos.z)/(SQUARE_SIZE*TREE_SQUARE_SIZE)*treesX;
trees[square].trees.erase(hash);
ResetPos(pos);
}
int CAdvTreeDrawer::AddFallingTree(float3 pos, float3 dir, int type)
{
FallingTree ft;
ft.pos=pos;
dir.y=0;
float s=dir.Length();
if(s>500)
return 0;
ft.dir=dir/s;
ft.speed=max(0.01f,s*0.0004f);
ft.type=type;
ft.fallPos=0;
fallingTrees.push_back(ft);
return 0;
}
void CAdvTreeDrawer::AddGrass(float3 pos)
{
grassDrawer->AddGrass(pos);
}
void CAdvTreeDrawer::RemoveGrass(int x, int z)
{
grassDrawer->RemoveGrass(x,z);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?