接下来我们来看方法

void CBFGroundDrawer::Draw(bool drawWaterReflection,bool drawUnitReflection,unsigned int overrideVP)
{
    if (wireframe) {
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    }

    drawWater=drawWaterReflection;

    int baseViewRadius=max(4,viewRadius);
    if(drawUnitReflection)
        viewRadius=(viewRadius/2)&0xfffffe;
    float zoom=45/camera->fov;
    viewRadius=(int)(viewRadius*sqrt(zoom));
    viewRadius+=viewRadius%2;                                           —-  viewRadius是观察半径

    va=GetVertexArray();
    va->Initialize();

    textures->DrawUpdate();

    int x,y;

    int neededLod=int(gu->viewRange/8/viewRadius*2);            —–镜头角度/8/镜头半径*2   这个什么意思呢?
    UpdateCamRestraints();                                                   —–更新镜头限制,获取边界值right,left

    invMapSizeX=1.0f/gs->mapx;                                           —-从全局变量获取X,Y
    invMapSizeY=1.0f/gs->mapy;

    glDisable(GL_BLEND);
    glEnable(GL_TEXTURE_2D);
    if(!overrideVP)
        glEnable(GL_CULL_FACE);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    SetupTextureUnits(drawWaterReflection,overrideVP);          —–载入单位质材
    bool inStrip=false;

    if(map->voidWater && !drawWater){
        glEnable(GL_ALPHA_TEST);
        glAlphaFunc(GL_GREATER,0.9f);
    }

  float camxpart=0,oldcamxpart;
    float camypart=0,oldcamypart;

    for(int bty=0;bty<numBigTexY;++bty){            //循环画出质材的方块(128*128的方块)写这段地形算法的人是绝对的天才。。。。。

      

        bigtexsuby=bty;

        //only process the necessary big squares in the x direction
        int sx=0;
        int ex=numBigTexX;
        float xtest,xtest2;
        const int bigSquareSize=128;

        std::vector<fline>::iterator fli;                     

                  —–迭代器里的fline等下用来历遍地图的边界,下面的left,和right用断点分析出来为一个left为个数为3的迭代器,而right个数为1,我们来查找它究竟是什么。请参照代码说明1

        for(fli=left.begin();fli!=left.end();fli++){                left.begin()     left.end()
            xtest=((fli->base/SQUARE_SIZE+fli->dir*(bty*bigSquareSize)));
            xtest2=((fli->base/SQUARE_SIZE+fli->dir*((bty*bigSquareSize)+bigSquareSize)));
            if(xtest>xtest2)
                xtest=xtest2;
            xtest=xtest/bigSquareSize;
            if(xtest>sx)
                sx=(int) xtest;                             取最大值储存入Sx中
        }
        for(fli=right.begin();fli!=right.end();fli++){
            xtest=((fli->base/SQUARE_SIZE+fli->dir*(bty*bigSquareSize)))+bigSquareSize;          向量长度*方块个数+ 向量方向*方块编号*方块大小+方块大小

            xtest2=((fli->base/SQUARE_SIZE+fli->dir*((bty*bigSquareSize)+bigSquareSize)))+bigSquareSize;

                                                                                                                  (向量长度*方块个数+ 向量方向*方块编号*方块大小+方块大小)+方块大小

            if(xtest<xtest2)
                xtest=xtest2;
            xtest=xtest/bigSquareSize;
            if(xtest<ex)
                ex=(int) xtest;                           取最小值存入ex中
        }
//        logOutput.Print(“%i %i”,sx,ex);
        for(int btx=sx;btx<ex;++btx){
            bigtexsubx=btx;

            if(DrawExtraTex() || !shadowHandler->drawShadows){
                textures->SetTexture(btx,bty);
                SetTexGen(1.0f/1024,1.0f/1024,-btx,-bty);
                if(overrideVP){
                     glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11, -btx,-bty,0,0);
                 }
            } else {
                textures->SetTexture(btx,bty);
                glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11, -btx,-bty,0,0);
            }

            for(int lod=1;lod<neededLod;lod*=2){ 

          —— 这个地方超级不好理解,我也是看了半天才弄懂一点 在这个lod的循环中,我们可以看到lod是1,也就是说,在第一次循环中

                                if(!inStrip){
                                    DrawVertexA(x,y);
                                    DrawVertexA(x,y+lod);
                                    inStrip=true;
                                }
                                DrawVertexA(x+lod,y);

                                DrawVertexA(x+lod,y+lod);

                                是一点连着一点的画的

 

                                当我们跟踪成寻随lod变化所话出来的图形时,我们可以看到lod的大小是与焦点到物体的距离成正比的


                                随着lod的变化,程序描绘的图形越来越远->越来越小。随着距离越远,程序描绘物体也就越小

                                而我们也越不需要更细致的描绘他,从而优化了图形的生成



 

 


                int cx=(int)(cam2->pos.x/(SQUARE_SIZE));
                int cy=(int)(cam2->pos.z/(SQUARE_SIZE));

                cx=(cx/lod)*lod;
                cy=(cy/lod)*lod;
                int hlod=lod>>1;
                int ysquaremod=((cy)%(2*lod))/lod;
                int xsquaremod=((cx)%(2*lod))/lod;

                oldcamxpart=camxpart;
                float cx2=(cx/(2*lod))*lod*2;
                camxpart=(cam2->pos.x/(SQUARE_SIZE)-cx2)/(lod*2);

                oldcamypart=camypart;
                float cy2=(cy/(2*lod))*lod*2;
                camypart=(cam2->pos.z/(SQUARE_SIZE)-cy2)/(lod*2);

                int minty=bty*128;
                int maxty=(bty+1)*128;
                int mintx=btx*128;
                int maxtx=(btx+1)*128;

                int minly=cy+(-viewRadius+3-ysquaremod)*lod;
                int maxly=cy+(viewRadius-1-ysquaremod)*lod;
                int minlx=cx+(-viewRadius+3-xsquaremod)*lod;
                int maxlx=cx+(viewRadius-1-xsquaremod)*lod;

                int xstart=max(minlx,mintx);
                int xend=min(maxlx,maxtx);
                int ystart=max(minly,minty);
                int yend=min(maxly,maxty);

                for(y=ystart;y<yend;y+=lod){
                    int xs=xstart;
                    int xe=xend;
                    int xtest,xtest2;
                    std::vector<fline>::iterator fli;
                    for(fli=left.begin();fli!=left.end();fli++){
                        xtest=((int)(fli->base/(SQUARE_SIZE)+fli->dir*y))/lod*lod-lod;
                        xtest2=((int)(fli->base/(SQUARE_SIZE)+fli->dir*(y+lod)))/lod*lod-lod;
                        if(xtest>xtest2)
                            xtest=xtest2;
                        if(xtest>xs)
                            xs=xtest;
                    }
                    for(fli=right.begin();fli!=right.end();fli++){
                        xtest=((int)(fli->base/(SQUARE_SIZE)+fli->dir*y))/lod*lod+lod;
                        xtest2=((int)(fli->base/(SQUARE_SIZE)+fli->dir*(y+lod)))/lod*lod+lod;
                        if(xtest<xtest2)
                            xtest=xtest2;
                        if(xtest<xe)
                            xe=xtest;
                    }

                    for(x=xs;x<xe;x+=lod){
                        if((lod==1) ||
                            (x>(cx)+viewRadius*hlod) || (x<(cx)-viewRadius*hlod) ||
                            (y>(cy)+viewRadius*hlod) || (y<(cy)-viewRadius*hlod)){  //normal terr锟絞
                                if(!inStrip){
                                    DrawVertexA(x,y);
                                    DrawVertexA(x,y+lod);
                                    inStrip=true;
                                }
                                DrawVertexA(x+lod,y);
                                DrawVertexA(x+lod,y+lod);
                            } else {  //inre begr锟絪ning mot f锟絜g锟絥de lod
                                if((x>=(cx)+viewRadius*hlod)){
                                    float h1=(heightData[(y)*heightDataX+x]+heightData[(y+lod)*heightDataX+x])*0.5f*(1-oldcamxpart)+heightData[(y+hlod)*heightDataX+x]*(oldcamxpart);
                                    float h2=(heightData[(y)*heightDataX+x]+heightData[(y)*heightDataX+x+lod])*0.5f*(1-oldcamxpart)+heightData[(y)*heightDataX+x+hlod]*(oldcamxpart);
                                    float h3=(heightData[(y+lod)*heightDataX+x]+heightData[(y)*heightDataX+x+lod])*0.5f*(1-oldcamxpart)+heightData[(y+hlod)*heightDataX+x+hlod]*(oldcamxpart);
                                    float h4=(heightData[(y+lod)*heightDataX+x]+heightData[(y+lod)*heightDataX+x+lod])*0.5f*(1-oldcamxpart)+heightData[(y+lod)*heightDataX+x+hlod]*(oldcamxpart);

                                    if(inStrip){
                                        EndStrip();
                                        inStrip=false;
                                    }
                                    DrawVertexA(x,y);
                                    DrawVertexA(x,y+hlod,h1);
                                    DrawVertexA(x+hlod,y,h2);
                                    DrawVertexA(x+hlod,y+hlod,h3);
                                    EndStrip();
                                    DrawVertexA(x,y+hlod,h1);
                                    DrawVertexA(x,y+lod);
                                    DrawVertexA(x+hlod,y+hlod,h3);
                                    DrawVertexA(x+hlod,y+lod,h4);
                                    EndStrip();
                                    DrawVertexA(x+hlod,y+lod,h4);
                                    DrawVertexA(x+lod,y+lod);
                                    DrawVertexA(x+hlod,y+hlod,h3);
                                    DrawVertexA(x+lod,y);
                                    DrawVertexA(x+hlod,y,h2);
                                    EndStrip();
                                }
                                if((x<=(cx)-viewRadius*hlod)){
                                    float h1=(heightData[(y)*heightDataX+x+lod]+heightData[(y+lod)*heightDataX+x+lod])*0.5f*(oldcamxpart)+heightData[(y+hlod)*heightDataX+x+lod]*(1-oldcamxpart);
                                    float h2=(heightData[(y)*heightDataX+x]+heightData[(y)*heightDataX+x+lod])*0.5f*(oldcamxpart)+heightData[(y)*heightDataX+x+hlod]*(1-oldcamxpart);
                                    float h3=(heightData[(y+lod)*heightDataX+x]+heightData[(y)*heightDataX+x+lod])*0.5f*(oldcamxpart)+heightData[(y+hlod)*heightDataX+x+hlod]*(1-oldcamxpart);
                                    float h4=(heightData[(y+lod)*heightDataX+x]+heightData[(y+lod)*heightDataX+x+lod])*0.5f*(oldcamxpart)+heightData[(y+lod)*heightDataX+x+hlod]*(1-oldcamxpart);

                                    if(inStrip){
                                        EndStrip();
                                        inStrip=false;
                                    }
                                    DrawVertexA(x+lod,y+hlod,h1);
                                    DrawVertexA(x+lod,y);
                                    DrawVertexA(x+hlod,y+hlod,h3);
                                    DrawVertexA(x+hlod,y,h2);
                                    EndStrip();
                                    DrawVertexA(x+lod,y+lod);
                                    DrawVertexA(x+lod,y+hlod,h1);
                                    DrawVertexA(x+hlod,y+lod,h4);
                                    DrawVertexA(x+hlod,y+hlod,h3);
                                    EndStrip();
                                    DrawVertexA(x+hlod,y,h2);
                                    DrawVertexA(x,y);
                                    DrawVertexA(x+hlod,y+hlod,h3);
                                    DrawVertexA(x,y+lod);
                                    DrawVertexA(x+hlod,y+lod,h4);
                                    EndStrip();
                                }
                                if((y>=(cy)+viewRadius*hlod)){
                                    float h1=(heightData[(y)*heightDataX+x]+heightData[(y)*heightDataX+x+lod])*0.5f*(1-oldcamypart)+heightData[(y)*heightDataX+x+hlod]*(oldcamypart);
                                    float h2=(heightData[(y)*heightDataX+x]+heightData[(y+lod)*heightDataX+x])*0.5f*(1-oldcamypart)+heightData[(y+hlod)*heightDataX+x]*(oldcamypart);
                                    float h3=(heightData[(y+lod)*heightDataX+x]+heightData[(y)*heightDataX+x+lod])*0.5f*(1-oldcamypart)+heightData[(y+hlod)*heightDataX+x+hlod]*(oldcamypart);
                                    float h4=(heightData[(y+lod)*heightDataX+x+lod]+heightData[(y)*heightDataX+x+lod])*0.5f*(1-oldcamypart)+heightData[(y+hlod)*heightDataX+x+lod]*(oldcamypart);

                                    if(inStrip){
                                        EndStrip();
                                        inStrip=false;
                                    }
                                    DrawVertexA(x,y);
                                    DrawVertexA(x,y+hlod,h2);
                                    DrawVertexA(x+hlod,y,h1);
                                    DrawVertexA(x+hlod,y+hlod,h3);
                                    DrawVertexA(x+lod,y);
                                    DrawVertexA(x+lod,y+hlod,h4);
                                    EndStrip();
                                    DrawVertexA(x,y+hlod,h2);
                                    DrawVertexA(x,y+lod);
                                    DrawVertexA(x+hlod,y+hlod,h3);
                                    DrawVertexA(x+lod,y+lod);
                                    DrawVertexA(x+lod,y+hlod,h4);
                                    EndStrip();
                                }
                                if((y<=(cy)-viewRadius*hlod)){
                                    float h1=(heightData[(y+lod)*heightDataX+x]+heightData[(y+lod)*heightDataX+x+lod])*0.5f*(oldcamypart)+heightData[(y+lod)*heightDataX+x+hlod]*(1-oldcamypart);
                                    float h2=(heightData[(y)*heightDataX+x]+heightData[(y+lod)*heightDataX+x])*0.5f*(oldcamypart)+heightData[(y+hlod)*heightDataX+x]*(1-oldcamypart);
                                    float h3=(heightData[(y+lod)*heightDataX+x]+heightData[(y)*heightDataX+x+lod])*0.5f*(oldcamypart)+heightData[(y+hlod)*heightDataX+x+hlod]*(1-oldcamypart);
                                    float h4=(heightData[(y+lod)*heightDataX+x+lod]+heightData[(y)*heightDataX+x+lod])*0.5f*(oldcamypart)+heightData[(y+hlod)*heightDataX+x+lod]*(1-oldcamypart);

                                    if(inStrip){
                                        EndStrip();
                                        inStrip=false;
                                    }
                                    DrawVertexA(x,y+hlod,h2);
                                    DrawVertexA(x,y+lod);
                                    DrawVertexA(x+hlod,y+hlod,h3);
                                    DrawVertexA(x+hlod,y+lod,h1);
                                    DrawVertexA(x+lod,y+hlod,h4);
                                    DrawVertexA(x+lod,y+lod);
                                    EndStrip();
                                    DrawVertexA(x+lod,y+hlod,h4);
                                    DrawVertexA(x+lod,y);
                                    DrawVertexA(x+hlod,y+hlod,h3);
                                    DrawVertexA(x,y);
                                    DrawVertexA(x,y+hlod,h2);
                                    EndStrip();
                                }
                            }
                    }
                    if(inStrip){
                        EndStrip();
                        inStrip=false;
                    }
                }
                //rita yttre begr锟絪nings yta mot n锟絫a lod
                if(maxlx<maxtx && maxlx>=mintx){
                    x=maxlx;
                    for(y=max(ystart-lod,minty);y<min(yend+lod,maxty);y+=lod){
                        DrawVertexA(x,y);
                        DrawVertexA(x,y+lod);
                        if(y%(lod*2)){
                            float h=((heightData[(y-lod)*heightDataX+x+lod]+heightData[(y+lod)*heightDataX+x+lod])*0.5f)*(1-camxpart)+heightData[(y)*heightDataX+x+lod]*(camxpart);
                            DrawVertexA(x+lod,y,h);
                            DrawVertexA(x+lod,y+lod);
                        } else {
                            DrawVertexA(x+lod,y);
                            float h=(heightData[(y)*heightDataX+x+lod]+heightData[(y+lod*2)*heightDataX+x+lod])*0.5f*(1-camxpart)+heightData[(y+lod)*heightDataX+x+lod]*(camxpart);
                            DrawVertexA(x+lod,y+lod,h);
                        }
                        EndStrip();
                    }
                }
                if(minlx>mintx && minlx<maxtx){
                    x=minlx-lod;
                    for(y=max(ystart-lod,minty);y<min(yend+lod,maxty);y+=lod){
                        if(y%(lod*2)){
                            float h=((heightData[(y-lod)*heightDataX+x]+heightData[(y+lod)*heightDataX+x])*0.5f)*(camxpart)+heightData[(y)*heightDataX+x]*(1-camxpart);
                            DrawVertexA(x,y,h);
                            DrawVertexA(x,y+lod);
                        } else {
                            DrawVertexA(x,y);
                            float h=(heightData[(y)*heightDataX+x]+heightData[(y+lod*2)*heightDataX+x])*0.5f*(camxpart)+heightData[(y+lod)*heightDataX+x]*(1-camxpart);
                            DrawVertexA(x,y+lod,h);
                        }
                        DrawVertexA(x+lod,y);
                        DrawVertexA(x+lod,y+lod);
                        EndStrip();
                    }
                }
                if(maxly<maxty && maxly>minty){
                    y=maxly;
                    int xs=max(xstart-lod,mintx);
                    int xe=min(xend+lod,maxtx);
                    int xtest,xtest2;
                    std::vector<fline>::iterator fli;
                    for(fli=left.begin();fli!=left.end();fli++){
                        xtest=((int)(fli->base/(SQUARE_SIZE)+fli->dir*y))/lod*lod-lod;
                        xtest2=((int)(fli->base/(SQUARE_SIZE)+fli->dir*(y+lod)))/lod*lod-lod;
                        if(xtest>xtest2)
                            xtest=xtest2;
                        if(xtest>xs)
                            xs=xtest;
                    }
                    for(fli=right.begin();fli!=right.end();fli++){
                        xtest=((int)(fli->base/(SQUARE_SIZE)+fli->dir*y))/lod*lod+lod;
                        xtest2=((int)(fli->base/(SQUARE_SIZE)+fli->dir*(y+lod)))/lod*lod+lod;
                        if(xtest<xtest2)
                            xtest=xtest2;
                        if(xtest<xe)
                            xe=xtest;
                    }
                    if(xs<xe){
                        x=xs;
                        if(x%(lod*2)){
                            DrawVertexA(x,y);
                            float h=((heightData[(y+lod)*heightDataX+x-lod]+heightData[(y+lod)*heightDataX+x+lod])*0.5f)*(1-camypart)+heightData[(y+lod)*heightDataX+x]*(camypart);
                            DrawVertexA(x,y+lod,h);
                        } else {
                            DrawVertexA(x,y);
                            DrawVertexA(x,y+lod);
                        }
                        for(x=xs;x<xe;x+=lod){
                            if(x%(lod*2)){
                                DrawVertexA(x+lod,y);
                                DrawVertexA(x+lod,y+lod);
                            } else {
                                DrawVertexA(x+lod,y);
                                float h=(heightData[(y+lod)*heightDataX+x+2*lod]+heightData[(y+lod)*heightDataX+x])*0.5f*(1-camypart)+heightData[(y+lod)*heightDataX+x+lod]*(camypart);
                                DrawVertexA(x+lod,y+lod,h);
                            }
                        }
                        EndStrip();
                    }
                }
                if(minly>minty && minly<maxty){
                    y=minly-lod;
                    int xs=max(xstart-lod,mintx);
                    int xe=min(xend+lod,maxtx);
                    int xtest,xtest2;
                    std::vector<fline>::iterator fli;
                    for(fli=left.begin();fli!=left.end();fli++){
                        xtest=((int)(fli->base/(SQUARE_SIZE)+fli->dir*y))/lod*lod-lod;
                        xtest2=((int)(fli->base/(SQUARE_SIZE)+fli->dir*(y+lod)))/lod*lod-lod;
                        if(xtest>xtest2)
                            xtest=xtest2;
                        if(xtest>xs)
                            xs=xtest;
                    }
                    for(fli=right.begin();fli!=right.end();fli++){
                        xtest=((int)(fli->base/(SQUARE_SIZE)+fli->dir*y))/lod*lod+lod;
                        xtest2=((int)(fli->base/(SQUARE_SIZE)+fli->dir*(y+lod)))/lod*lod+lod;
                        if(xtest<xtest2)
                            xtest=xtest2;
                        if(xtest<xe)
                            xe=xtest;
                    }
                    if(xs<xe){
                        x=xs;
                        if(x%(lod*2)){
                            float h=((heightData[(y)*heightDataX+x-lod]+heightData[(y)*heightDataX+x+lod])*0.5f)*(camypart)+heightData[(y)*heightDataX+x]*(1-camypart);
                            DrawVertexA(x,y,h);
                            DrawVertexA(x,y+lod);
                        } else {
                            DrawVertexA(x,y);
                            DrawVertexA(x,y+lod);
                        }
                        for(x=xs;x<xe;x+=lod){
                            if(x%(lod*2)){
                                DrawVertexA(x+lod,y);
                                DrawVertexA(x+lod,y+lod);
                            } else {
                                float h=(heightData[(y)*heightDataX+x+2*lod]+heightData[(y)*heightDataX+x])*0.5f*(camypart)+heightData[(y)*heightDataX+x+lod]*(1-camypart);
                                DrawVertexA(x+lod,y,h);
                                DrawVertexA(x+lod,y+lod);
                            }
                        }
                        EndStrip();
                    }
                }
            }
            DrawGroundVertexArray();
        }
    }
    ResetTextureUnits(drawWaterReflection,overrideVP);
    glDisable(GL_CULL_FACE);

    if (wireframe) {
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }

    if(map->voidWater && !drawWater){
        glDisable(GL_ALPHA_TEST);
    }

    if(map->hasWaterPlane)
    {
        glDisable(GL_TEXTURE_2D);
        glColor3f(map->waterPlaneColor.x, map->waterPlaneColor.y, map->waterPlaneColor.z);
        glBegin(GL_QUADS);//water color edge of map <0
        if(!drawWaterReflection){
            float xsize=gs->mapx*SQUARE_SIZE/4;
            float ysize=gs->mapy*SQUARE_SIZE/4;
            for(y=-4;y<8;++y)
                for(int x=-4;x<8;++x)
                    if(x>3 || x<0 || y>3 || y<0 || camera->pos.x<0 || camera->pos.z<0 || camera->pos.x>float3::maxxpos || camera->pos.z>float3::maxzpos){
                            glVertex3f(x*xsize,-200,y*ysize);
                            glVertex3f((x+1)*xsize,-200,y*ysize);
                            glVertex3f((x+1)*xsize,-200,(y+1)*ysize);
                            glVertex3f(x*xsize,-200,(y+1)*ysize);
                    }
        }
        glEnd();
    }

    if(groundDecals && !(drawWaterReflection || drawUnitReflection))
        groundDecals->Draw();

    glEnable(GL_ALPHA_TEST);
    glEnable(GL_TEXTURE_2D);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

//    sky->SetCloudShadow(1);
//    if(drawWaterReflection)
//        treeDistance*=0.5f;

    ph->DrawGroundFlashes();
    if(treeDrawer->drawTrees){
        if(DrawExtraTex()){
            glActiveTextureARB(GL_TEXTURE1_ARB);
            glEnable(GL_TEXTURE_2D);
            glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_ADD_SIGNED_ARB);
            glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB,GL_PREVIOUS_ARB);
            glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB,GL_TEXTURE);
            glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_MODULATE);
            glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB,GL_PREVIOUS_ARB);
            glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_ARB,GL_TEXTURE);
            glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
            glBindTexture(GL_TEXTURE_2D, infoTex);
            SetTexGen(1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,0);
          glActiveTextureARB(GL_TEXTURE0_ARB);
        }
        treeDrawer->Draw(drawWaterReflection || drawUnitReflection);
        if(DrawExtraTex()){
            glActiveTextureARB(GL_TEXTURE1_ARB);
            glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
            glDisable(GL_TEXTURE_GEN_S);
            glDisable(GL_TEXTURE_GEN_T);
            glDisable(GL_TEXTURE_2D);
          glActiveTextureARB(GL_TEXTURE0_ARB);
        }
    }

    glDisable(GL_ALPHA_TEST);

    glDisable(GL_TEXTURE_2D);
    viewRadius=baseViewRadius;

}

又是一个吐血加头晕的方法, 其实这个方法的关键地方就是DrawVertexA()这个方法,这个方法有两个重载:

inline void CBFGroundDrawer::DrawVertexA(int x,int y)
{
    float height=heightData[y*heightDataX+x];
    if(drawWater && height<0){
        height*=2;
    }

    va->AddVertex0(float3(x*SQUARE_SIZE,height,y*SQUARE_SIZE));
}

inline void CBFGroundDrawer::DrawVertexA(int x,int y,float height)
{
    if(drawWater && height<0){
        height*=2;
    }
    va->AddVertex0(float3(x*SQUARE_SIZE,height,y*SQUARE_SIZE));

}

画图的关键地方就是找出正确的x,y,height ,然后一点一点的画出来,我们再看va->AddVerterx0()这个方法

void CVertexArray::AddVertex0(const float3& pos)
{
    if(drawIndex>drawArraySize-10)
        EnlargeDrawArray();

    drawArray[drawIndex++]=pos.x;
    drawArray[drawIndex++]=pos.y;
    drawArray[drawIndex++]=pos.z;
}

意思很明显,就是将x,y,z的坐标存入一个叫drawArray的数列之中。然后。。。。

void CVertexArray::DrawArray0(int drawType,int stride)
{
    if(stripIndex==0 || stripArray[stripIndex-1]!=drawIndex)
        EndStrip();
    glVertexPointer(3,GL_FLOAT,stride,&drawArray[0]);
    glEnableClientState(GL_VERTEX_ARRAY);
    int oldIndex=0;
    for(int a=0;a<stripIndex;a++){
        glDrawArrays(drawType,oldIndex*4/stride,stripArray[a]*4/stride-oldIndex*4/stride);
        oldIndex=stripArray[a];
    }
    glDisableClientState(GL_VERTEX_ARRAY);                        

}

调用glDrawArrays将这些点画出来。

现在我们反过来考察,前面的传入x,y,z究竟是什么东西。大家现在可以回过头看我前面的注释。

*代码说明1——————————————————————————–

———————————————————————————————-

要了接left,和right的作用,我们要看看以下这两个方法

void CBFGroundDrawer::UpdateCamRestraints(void)
{
    left.clear();
    right.clear();

    //Add restraints for camera sides
    AddFrustumRestraint(cam2->bottom);
    AddFrustumRestraint(cam2->top);
    AddFrustumRestraint(cam2->rightside);
    AddFrustumRestraint(cam2->leftside);

    //Add restraint for maximum view distance
    fline temp;
    float3 up(0,1,0);
    float3 side=cam2->forward;
    float3 camHorizontal=cam2->forward;
    camHorizontal.y=0;
    camHorizontal.Normalize();
    float3 b=up.cross(camHorizontal);            //get vector for collision between frustum and horizontal plane
    if(fabs(b.z)>0.0001f){
        temp.dir=b.x/b.z;                //set direction to that
        float3 c=b.cross(camHorizontal);            //get vector from camera to collision line
        float3 colpoint;                //a point on the collision line

        if(side.y>0)
            colpoint=cam2->pos+camHorizontal*gu->viewRange*1.05f-c*(cam2->pos.y/c.y);
        else
            colpoint=cam2->pos+camHorizontal*gu->viewRange*1.05f-c*((cam2->pos.y-255/3.5f)/c.y);

        temp.base=colpoint.x-colpoint.z*temp.dir;    //get intersection between colpoint and z axis
        if(b.z>0){
            left.push_back(temp);
        }else{
            right.push_back(temp);
        }

    }

}

void CBFGroundDrawer::AddFrustumRestraint(float3 side)
{
    fline temp;
    float3 up(0,1,0);        

    float3 b=up.cross(side);        //get vector for collision between frustum and horizontal plane   (计算side和y轴的垂线)
    if(fabs(b.z)<0.0001f)  fabs为取绝对值
        b.z=0.0001f;
    {
        temp.dir=b.x/b.z;                //set direction to that                                  计算向量方向值

        float3 c=b.cross(side);            //get vector from camera to collision line      这里其实是进行 (y1*z2-z1*y2,z1*x2-x1*z2,x1*y2-y1*x2) 这样的计算

                                                                                                    这是什么意思?这是计算正交向量的意思(x1,y1,z1)(x2,y2,z2)计算他的垂直变量

        float3 colpoint;                //a point on the collision line

        if(side.y>0)
            colpoint=cam2->pos-c*((cam2->pos.y-(readmap->minheight-100))/c.y);
        else
            colpoint=cam2->pos-c*((cam2->pos.y-(readmap->maxheight+30))/c.y);

        temp.base=colpoint.x-colpoint.z*temp.dir;    //get intersection between colpoint and z axis        与Z轴的X方向的距离
        if(b.z>0){
            left.push_back(temp);
        }else{
            right.push_back(temp);
        }
    }

}

关键我们看 UpdateCamRestraints(void)这个方法,在这方法中一个temp的数据被添加left和right迭代器中。我们来考察得出temp的这一段算法

 

*代码说明1完——————————————————————————–

———————————————————————————————-

 

 

 

 

 

 

posted on
2008-08-07 15:40 
konyel 
阅读(1248
评论(0
编辑 
收藏 
举报

版权声明:本文为konyel原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/konyel/articles/1263027.html