📄 bfgrounddrawer.cpp
字号:
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�snings yta mot n�ta 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);
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);
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();
}
glDisable(GL_POLYGON_OFFSET_FILL);
glDisable(GL_CULL_FACE);
glDisable( GL_VERTEX_PROGRAM_ARB );
}
void CBFGroundDrawer::SetupTextureUnits(bool drawReflection, unsigned int overrideVP)
{
glColor4f(1,1,1,1);
if (DrawExtraTex()) {
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, map->GetShadingTexture());
SetTexGen(1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,0);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glActiveTextureARB(GL_TEXTURE2_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
if (map->detailTex) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, map->detailTex);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_ADD_SIGNED_ARB);
SetTexGen(0.02f,0.02f,-floor(camera->pos.x*0.02f),-floor(camera->pos.z*0.02f));
} else {
glDisable (GL_TEXTURE_2D);
}
glActiveTextureARB(GL_TEXTURE3_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, infoTex);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_ADD_SIGNED_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
SetTexGen(1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,0);
if(overrideVP){
glEnable( GL_VERTEX_PROGRAM_ARB );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, overrideVP );
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10, 1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,1);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, 1.0f/1024,1.0f/1024,0,1);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, -floor(camera->pos.x*0.02f),-floor(camera->pos.z*0.02f),0,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,14, 0.02f,0.02f,0,1);
if(drawReflection){
glAlphaFunc(GL_GREATER,0.9f);
glEnable(GL_ALPHA_TEST);
}
}
}
else if (shadowHandler->drawShadows) {
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, groundFPShadow );
glEnable( GL_FRAGMENT_PROGRAM_ARB );
float3 ac=map->ambientColor*(210.0f/255.0f);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,10, ac.x,ac.y,ac.z,1);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,11, 0,0,0,map->shadowDensity);
glActiveTextureARB(GL_TEXTURE0_ARB);
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, map->GetShadingTexture());
glActiveTextureARB(GL_TEXTURE2_ARB);
if (map->detailTex) {
glBindTexture(GL_TEXTURE_2D, map->detailTex);
} else {
glBindTexture(GL_TEXTURE_2D, 0);
}
glActiveTextureARB(GL_TEXTURE3_ARB);
glActiveTextureARB(GL_TEXTURE4_ARB);
glBindTexture(GL_TEXTURE_2D, shadowHandler->shadowTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
glActiveTextureARB(GL_TEXTURE0_ARB);
if (drawReflection) {
glAlphaFunc(GL_GREATER,0.8f);
glEnable(GL_ALPHA_TEST);
}
if (overrideVP) {
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, overrideVP );
} else {
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, groundVP );
}
glEnable( GL_VERTEX_PROGRAM_ARB );
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10, 1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,1);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, 1.0f/1024,1.0f/1024,0,1);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, -floor(camera->pos.x*0.02f),-floor(camera->pos.z*0.02f),0,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,14, 0.02f,0.02f,0,1);
glMatrixMode(GL_MATRIX0_ARB);
glLoadMatrixf(shadowHandler->shadowMatrix.m);
glMatrixMode(GL_MODELVIEW);
} else {
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, map->GetShadingTexture ());
SetTexGen(1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,0);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glActiveTextureARB(GL_TEXTURE2_ARB);
if (map->detailTex) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, map->detailTex);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_ADD_SIGNED_ARB);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);
SetTexGen(0.02f,0.02f,-floor(camera->pos.x*0.02f),-floor(camera->pos.z*0.02f));
} else {
glDisable (GL_TEXTURE_2D);
}
if (overrideVP) {
glEnable( GL_VERTEX_PROGRAM_ARB );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, overrideVP );
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10, 1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,1);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, 1.0f/1024,1.0f/1024,0,1);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, -floor(camera->pos.x*0.02f),-floor(camera->pos.z*0.02f),0,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,14, 0.02f,0.02f,0,1);
if (drawReflection) {
glAlphaFunc(GL_GREATER,0.9f);
glEnable(GL_ALPHA_TEST);
}
}
}
glActiveTextureARB(GL_TEXTURE0_ARB);
}
void CBFGroundDrawer::ResetTextureUnits(bool drawReflection,unsigned int overrideVP)
{
if(DrawExtraTex() || !shadowHandler->drawShadows){
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE2_ARB);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glActiveTextureARB(GL_TEXTURE3_ARB);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glActiveTextureARB(GL_TEXTURE0_ARB);
if(overrideVP){
glDisable( GL_VERTEX_PROGRAM_ARB );
if(drawReflection){
glDisable(GL_ALPHA_TEST);
}
}
} else {
glDisable( GL_VERTEX_PROGRAM_ARB );
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glActiveTextureARB(GL_TEXTURE4_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
glActiveTextureARB(GL_TEXTURE0_ARB);
if(drawReflection){
glDisable(GL_ALPHA_TEST);
}
}
}
void CBFGroundDrawer::AddFrustumRestraint(const float3& side)
{
fline temp;
float3 up(0,1,0);
float3 b=up.cross(side); //get vector for collision between frustum and horizontal plane
if(fabs(b.z)<0.0001f)
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
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
if(b.z>0){
left.push_back(temp);
}else{
right.push_back(temp);
}
}
}
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::IncreaseDetail()
{
viewRadius+=2;
logOutput << "ViewRadius is now " << viewRadius << "\n";
}
void CBFGroundDrawer::DecreaseDetail()
{
viewRadius-=2;
logOutput << "ViewRadius is now " << viewRadius << "\n";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -