📄 dynwater.cpp
字号:
for(fli=left.begin();fli!=left.end();fli++){
xtest=((int)(fli->base/(WSQUARE_SIZE)+fli->dir*y))/lod*lod-lod;
xtest2=((int)(fli->base/(WSQUARE_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/(WSQUARE_SIZE)+fli->dir*y))/lod*lod+lod;
xtest2=((int)(fli->base/(WSQUARE_SIZE)+fli->dir*(y+lod)))/lod*lod+lod;
if(xtest<xtest2)
xtest=xtest2;
if(xtest<xe)
xe=xtest;
}
for(int 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 terrain
if(!inStrip){
DrawVertexA(x,y);
DrawVertexA(x,y+lod);
inStrip=true;
}
DrawVertexA(x+lod,y);
DrawVertexA(x+lod,y+lod);
} else { //inre begr�sning mot f�eg�nde lod
if((x>=(cx)+viewRadius*hlod)){
if(inStrip){
va->EndStrip();
inStrip=false;
}
DrawVertexA(x,y);
DrawVertexA(x,y+hlod);
DrawVertexA(x+hlod,y);
DrawVertexA(x+hlod,y+hlod);
va->EndStrip();
DrawVertexA(x,y+hlod);
DrawVertexA(x,y+lod);
DrawVertexA(x+hlod,y+hlod);
DrawVertexA(x+hlod,y+lod);
va->EndStrip();
DrawVertexA(x+hlod,y+lod);
DrawVertexA(x+lod,y+lod);
DrawVertexA(x+hlod,y+hlod);
DrawVertexA(x+lod,y);
DrawVertexA(x+hlod,y);
va->EndStrip();
}
else if((x<=(cx)-viewRadius*hlod)){
if(inStrip){
va->EndStrip();
inStrip=false;
}
DrawVertexA(x+lod,y+hlod);
DrawVertexA(x+lod,y);
DrawVertexA(x+hlod,y+hlod);
DrawVertexA(x+hlod,y);
va->EndStrip();
DrawVertexA(x+lod,y+lod);
DrawVertexA(x+lod,y+hlod);
DrawVertexA(x+hlod,y+lod);
DrawVertexA(x+hlod,y+hlod);
va->EndStrip();
DrawVertexA(x+hlod,y);
DrawVertexA(x,y);
DrawVertexA(x+hlod,y+hlod);
DrawVertexA(x,y+lod);
DrawVertexA(x+hlod,y+lod);
va->EndStrip();
}
else if((y>=(cy)+viewRadius*hlod)){
if(inStrip){
va->EndStrip();
inStrip=false;
}
DrawVertexA(x,y);
DrawVertexA(x,y+hlod);
DrawVertexA(x+hlod,y);
DrawVertexA(x+hlod,y+hlod);
DrawVertexA(x+lod,y);
DrawVertexA(x+lod,y+hlod);
va->EndStrip();
DrawVertexA(x,y+hlod);
DrawVertexA(x,y+lod);
DrawVertexA(x+hlod,y+hlod);
DrawVertexA(x+lod,y+lod);
DrawVertexA(x+lod,y+hlod);
va->EndStrip();
}
else if((y<=(cy)-viewRadius*hlod)){
if(inStrip){
va->EndStrip();
inStrip=false;
}
DrawVertexA(x,y+hlod);
DrawVertexA(x,y+lod);
DrawVertexA(x+hlod,y+hlod);
DrawVertexA(x+hlod,y+lod);
DrawVertexA(x+lod,y+hlod);
DrawVertexA(x+lod,y+lod);
va->EndStrip();
DrawVertexA(x+lod,y+hlod);
DrawVertexA(x+lod,y);
DrawVertexA(x+hlod,y+hlod);
DrawVertexA(x,y);
DrawVertexA(x,y+hlod);
va->EndStrip();
}
}
}
if(inStrip){
va->EndStrip();
inStrip=false;
}
}
}
va->DrawArray0(GL_TRIANGLE_STRIP);
}
void CDynWater::DrawDetailNormalTex(void)
{
for(int a=0;a<8;++a){
glActiveTextureARB(GL_TEXTURE0_ARB+a);
glBindTexture(GL_TEXTURE_2D,rawBumpTexture[0]);
}
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, detailNormalTex, 0);
glViewport(0,0,256,256);
int status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
logOutput.Print("FBO not ready5");
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, dwDetailNormalFP );
glEnable( GL_FRAGMENT_PROGRAM_ARB );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, dwDetailNormalVP );
glEnable( GL_VERTEX_PROGRAM_ARB );
float swh=0.05f; //height of detail normal waves
float lwh=1.0f; //height of larger ambient waves
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 9, gs->frameNum, 0, 0, 0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 10, 5, 0, 0, 1.0f/120); //controls the position and speed of the waves
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 11, 14, 0, 0, 1.0f/90);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 12, 29, 0, 0, 1.0f/55);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 13, 9, 4, 0, 1.0f/100);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 14, -5, 14, 0, 1.0f/90);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 15, 27, 27, 0, 1.0f/75);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 16, -3, -5, 0, 1.0f/100);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 17, -10, 24, 0, 1.0f/60);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,0, 0.2f*swh, 0.0f*swh, 0.7f*lwh, 0); //controls the height of the waves
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,1, 0.2f*swh, 0.0f*swh, 0.7f*lwh, 0);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,2, 0.2f*swh, 0.0f*swh, 0.7f*lwh, 0);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,3, 0.2f*swh, 0.01f*swh, 0.4f*lwh, 0);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,4, 0.07f*swh, 0.2f*swh, 0.7f*lwh, 0);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,5, 0.2f*swh, 0.2f*swh, 0.7f*lwh, 0);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,6, 0.12f*swh, 0.2f*swh, 0.7f*lwh, 0);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,7, 0.08f*swh, 0.2f*swh, 0.7f*lwh, 0);
//update detail normals
glBegin(GL_QUADS);
glTexCoord2f(0,0);glVertex3f(0,0,0);
glTexCoord2f(0,1);glVertex3f(0,1,0);
glTexCoord2f(1,1);glVertex3f(1,1,0);
glTexCoord2f(1,0);glVertex3f(1,0,0);
glEnd();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glDisable( GL_VERTEX_PROGRAM_ARB );
glFlush();
glBindTexture(GL_TEXTURE_2D,detailNormalTex);
glGenerateMipmapEXT(GL_TEXTURE_2D);
}
void CDynWater::AddShipWakes()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, waveTex1, 0);
glViewport(0,0,1024,1024);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,1,0,1,-1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLenum status;
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
logOutput.Print("FBO not ready6");
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, dwAddSplashFP );
glEnable( GL_FRAGMENT_PROGRAM_ARB );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, dwAddSplashVP );
glEnable( GL_VERTEX_PROGRAM_ARB );
glDisable(GL_CULL_FACE);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 10, 1.0f/WF_SIZE, 1.0f/WF_SIZE, 0, 1);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 11, -(oldCamPosBig.x-WH_SIZE)/WF_SIZE, -(oldCamPosBig.z-WH_SIZE)/WF_SIZE, 0, 0);
CVertexArray* va=GetVertexArray();
va->Initialize();
CVertexArray* va2=GetVertexArray(); //never try to get more than 2 at once
va2->Initialize();
for(std::list<CUnit*>::iterator ui=uh->activeUnits.begin(); ui!=uh->activeUnits.end();++ui){
CUnit* unit=*ui;
if(unit->moveType && unit->floatOnWater && unit->mobility && !unit->unitDef->canhover){ //boat
float speedf=unit->speed.Length2D();
float3 pos=unit->pos;
if(fabs(pos.x-camPosBig.x)>WH_SIZE-50 || fabs(pos.z-camPosBig.z)>WH_SIZE-50)
continue;
if(!(unit->losStatus[gu->myAllyTeam] & LOS_INLOS) && !gu->spectatingFullView)
continue;
if(pos.y>-4 && pos.y<1){
float3 frontAdd=unit->frontdir*unit->radius*0.75f;
float3 sideAdd=unit->rightdir*unit->radius*0.18f;
float depth=sqrt(sqrt(unit->mass));
float3 n(depth, 0.04f*speedf*depth, depth);
va->AddVertexTN(pos+frontAdd+sideAdd,0,0,n);
va->AddVertexTN(pos+frontAdd-sideAdd,1,0,n);
va->AddVertexTN(pos-frontAdd-sideAdd,1,1,n);
va->AddVertexTN(pos-frontAdd+sideAdd,0,1,n);
}
} else if(unit->moveType && unit->unitDef->canhover && unit->mobility){ //hover
float3 pos=unit->pos;
if(fabs(pos.x-camPosBig.x)>WH_SIZE-50 || fabs(pos.z-camPosBig.z)>WH_SIZE-50)
continue;
if(!(unit->losStatus[gu->myAllyTeam] & LOS_INLOS) && !gu->spectatingFullView)
continue;
if(pos.y>-4 && pos.y<4){
float3 frontAdd=unit->frontdir*unit->radius*0.75f;
float3 sideAdd=unit->rightdir*unit->radius*0.75f;
float depth=sqrt(sqrt(unit->mass))*0.4f;
float3 n(depth, 0.05f*depth, depth);
va2->AddVertexTN(pos+frontAdd+sideAdd,0,0,n);
va2->AddVertexTN(pos+frontAdd-sideAdd,1,0,n);
va2->AddVertexTN(pos-frontAdd-sideAdd,1,1,n);
va2->AddVertexTN(pos-frontAdd+sideAdd,0,1,n);
}
}
}
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,boatShape);
va->DrawArrayTN(GL_QUADS);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,hoverShape);
va2->DrawArrayTN(GL_QUADS);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDisable(GL_BLEND);
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glDisable( GL_VERTEX_PROGRAM_ARB );
glFlush();
}
void CDynWater::AddExplosions()
{
if(explosions.empty())
return;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, waveTex1, 0);
glViewport(0,0,1024,1024);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,1,0,1,-1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,splashTex);
GLenum status;
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
logOutput.Print("FBO not ready7");
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, dwAddSplashFP );
glEnable( GL_FRAGMENT_PROGRAM_ARB );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, dwAddSplashVP );
glEnable( GL_VERTEX_PROGRAM_ARB );
glDisable(GL_CULL_FACE);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 10, 1.0f/WF_SIZE, 1.0f/WF_SIZE, 0, 1);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 11, -(oldCamPosBig.x-WH_SIZE)/WF_SIZE, -(oldCamPosBig.z-WH_SIZE)/WF_SIZE, 0, 0);
CVertexArray* va=GetVertexArray();
va->Initialize();
for(std::vector<Explosion>::iterator ei=explosions.begin(); ei!=explosions.end();++ei){
Explosion& explo=*ei;
float3 pos=explo.pos;
if(fabs(pos.x-camPosBig.x)>WH_SIZE-50 || fabs(pos.z-camPosBig.z)>WH_SIZE-50)
continue;
float inv=1.01f;
if(pos.y<0){
if(pos.y<-explo.radius*0.5f)
inv=0.99f;
pos.y=pos.y*-0.5f;
}
float size=explo.radius-pos.y;
if(size<8)
continue;
float strength=explo.strength * (size/explo.radius)*0.5f;
float3 n(strength, strength*0.005f, strength*inv);
va->AddVertexTN(pos+float3(1,0,1)*size,0,0,n);
va->AddVertexTN(pos+float3(-1,0,1)*size,1,0,n);
va->AddVertexTN(pos+float3(-1,0,-1)*size,1,1,n);
va->AddVertexTN(pos+float3(1,0,-1)*size,0,1,n);
}
explosions.clear();
va->DrawArrayTN(GL_QUADS);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDisable(GL_BLEND);
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glDisable( GL_VERTEX_PROGRAM_ARB );
glFlush();
}
void CDynWater::AddExplosion(const float3& pos, float strength, float size)
{
if(pos.y>size || size < 8)
return;
explosions.push_back(Explosion(pos,min(size*20,strength),size));
}
void CDynWater::DrawUpdateSquare(float dx,float dy, int* resetTexs)
{
float startx=max(0.f, -dx/WF_SIZE);
float starty=max(0.f, -dy/WF_SIZE);
float endx=min(1.f, 1-dx/WF_SIZE);
float endy=min(1.f, 1-dy/WF_SIZE);
DrawSingleUpdateSquare(startx,starty,endx,endy);
int a=0;
while(resetTexs[a]>=0){
glActiveTextureARB(GL_TEXTURE0_ARB+resetTexs[a]);
glBindTexture(GL_TEXTURE_2D, zeroTex);
++a;
}
glActiveTextureARB(GL_TEXTURE0_ARB);
if(startx>0){
DrawSingleUpdateSquare(0,0,startx,1);
} else if(endx<1){
DrawSingleUpdateSquare(endx,0,1,1);
}
if(starty>0){
DrawSingleUpdateSquare(startx,0,endx,starty);
} else if (endy<1){
DrawSingleUpdateSquare(startx,endy,endx,1);
}
}
void CDynWater::DrawSingleUpdateSquare(float startx,float starty,float endx,float endy)
{
float texstart=0.1f/1024;
float texend=1023.9f/1024;
float texdif=texend-texstart;
CVertexArray* va=GetVertexArray();
va->Initialize();
va->AddVertexT(float3(startx,starty,0),texstart + startx*texdif,texstart + starty*texdif);
va->AddVertexT(float3(startx,endy,0),texstart + startx*texdif,texstart + endy*texdif );
va->AddVertexT(float3(endx,endy,0),texstart + endx*texdif,texstart + endy*texdif );
va->AddVertexT(float3(endx,starty,0),texstart + endx*texdif,texstart + starty*texdif);
va->DrawArrayT(GL_QUADS);
}
void CDynWater::DrawOuterSurface(void)
{
CVertexArray* va=GetVertexArray();
va->Initialize();
float size=WF_SIZE;
float size2=WF_SIZE/16;
float posx=camPosBig2.x-WH_SIZE;
float posy=camPosBig2.z-WH_SIZE;
for(int y=-1;y<=1;++y){
for(int x=-1;x<=1;++x){
if(x==0 && y==0)
continue;
for(int y2=0;y2<16;++y2){
for(int x2=0;x2<16;++x2){
va->AddVertex0(float3(posx+x*size+(x2+0)*size2,0,posy+y*size+(y2+0)*size2));
va->AddVertex0(float3(posx+x*size+(x2+1)*size2,0,posy+y*size+(y2+0)*size2));
va->AddVertex0(float3(posx+x*size+(x2+1)*size2,0,posy+y*size+(y2+1)*size2));
va->AddVertex0(float3(posx+x*size+(x2+0)*size2,0,posy+y*size+(y2+1)*size2));
}
}
}
}
va->DrawArray0(GL_QUADS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -