📄 dynwater.cpp
字号:
glClipPlane(GL_CLIP_PLANE2 ,plane);
gd->Draw(true);
shadowHandler->drawShadows=drawShadows;
unitDrawer->Draw(true);
featureHandler->Draw();
ph->Draw(true);
luaCallIns.DrawWorldReflection();
sky->DrawSun();
game->SetDrawMode(CGame::normalDraw);
drawReflection=false;
glDisable(GL_CLIP_PLANE2);
glColorMask(1,1,1,1);
glBindTexture(GL_TEXTURE_2D, reflectTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,512,512);
glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
glClearColor(FogLand[0],FogLand[1],FogLand[2],1);
delete camera;
camera = realCam;
camera->Update(false);
}
void CDynWater::DrawRefraction(CGame* game)
{
drawRefraction=true;
camera->Update(false);
refractRight=camera->right;
refractUp=camera->up;
refractForward=camera->forward;
glViewport(0,0,refractSize,refractSize);
glClearColor(FogLand[0],FogLand[1],FogLand[2],1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float3 oldsun=unitDrawer->unitSunColor;
float3 oldambient=unitDrawer->unitAmbientColor;
unitDrawer->unitSunColor*=float3(0.5f,0.7f,0.9f);
unitDrawer->unitAmbientColor*=float3(0.6f,0.8f,1.0f);
game->SetDrawMode(CGame::refractionDraw);
CBaseGroundDrawer *gd = readmap->GetGroundDrawer();
gd->Draw(false,false,dwGroundRefractVP);
glEnable(GL_CLIP_PLANE2);
double plane[4]={0,-1,0,2};
glClipPlane(GL_CLIP_PLANE2 ,plane);
drawReflection=true;
unitDrawer->Draw(false,true);
featureHandler->Draw();
drawReflection=false;
ph->Draw(false,true);
luaCallIns.DrawWorldRefraction();
glDisable(GL_CLIP_PLANE2);
game->SetDrawMode(CGame::normalDraw);
drawRefraction=false;
glBindTexture(GL_TEXTURE_2D, refractTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,refractSize,refractSize);
glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
glClearColor(FogLand[0],FogLand[1],FogLand[2],1);
unitDrawer->unitSunColor=oldsun;
unitDrawer->unitAmbientColor=oldambient;
}
void CDynWater::DrawWaves(void)
{
float dx=camPosBig.x-oldCamPosBig.x;
float dy=camPosBig.z-oldCamPosBig.z;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,1,0,1,-1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D,waveTex3);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE2_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE3_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE4_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE5_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE0_ARB);
GLenum status;
float start=0.1f/1024;
float end=1023.9f/1024;
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,8, -1.0f/1024, 1.0f/1024, 0,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9, 0, 1.0f/1024, 0,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10, 1.0f/1024, 1.0f/1024, 0,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11, 1.0f/1024, 0, 0,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, float(WF_SIZE)/(gs->pwr2mapx*SQUARE_SIZE), float(WF_SIZE)/(gs->pwr2mapy*SQUARE_SIZE), 0,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13, (camPosBig.x-WH_SIZE)/(gs->pwr2mapx*SQUARE_SIZE), (camPosBig.z-WH_SIZE)/(gs->pwr2mapy*SQUARE_SIZE), 0, 0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,14, dx/WF_SIZE, dy/WF_SIZE, 0,0);
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,15, (camPosBig.x-WH_SIZE)/WF_SIZE*4, (camPosBig.x-WH_SIZE)/WF_SIZE*4, 0,0);
//////////////////////////////////////
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, waveTex3, 0);
glViewport(0,0,1024,1024);
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
logOutput.Print("FBO not ready2");
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex2);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex1);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glActiveTextureARB(GL_TEXTURE2_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex1);
glActiveTextureARB(GL_TEXTURE3_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex1);
glActiveTextureARB(GL_TEXTURE4_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex1);
glActiveTextureARB(GL_TEXTURE5_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex1);
glActiveTextureARB(GL_TEXTURE6_ARB);
glBindTexture(GL_TEXTURE_2D, readmap->GetShadingTexture ());
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, waveFP2 );
glEnable( GL_FRAGMENT_PROGRAM_ARB );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, waveVP2 );
glEnable( GL_VERTEX_PROGRAM_ARB );
//update flows pass
int resetTexs[]={0,1,2,3,4,5,-1};
DrawUpdateSquare(dx,dy,resetTexs);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glFlush();
///////////////////////////////////////
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, waveTex2, 0);
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
logOutput.Print("FBO not ready1");
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex1);
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex3);
glActiveTextureARB(GL_TEXTURE2_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex3);
glActiveTextureARB(GL_TEXTURE3_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex3);
glActiveTextureARB(GL_TEXTURE4_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex3);
glActiveTextureARB(GL_TEXTURE5_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex3);
glActiveTextureARB(GL_TEXTURE6_ARB);
glBindTexture(GL_TEXTURE_2D,detailNormalTex);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, waveFP );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, waveVP );
//update height pass
int resetTexs2[]={0,-1};
DrawUpdateSquare(dx,dy,resetTexs2);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glFlush();
////////////////////////////////
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex2);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex2);
glActiveTextureARB(GL_TEXTURE2_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex2);
glActiveTextureARB(GL_TEXTURE3_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex2);
glActiveTextureARB(GL_TEXTURE4_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE5_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE6_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, waveTex1, 0);
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
logOutput.Print("FBO not ready3");
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, waveNormalFP );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, waveNormalVP );
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,0, 0, 0, W_SIZE*2, 0);
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,1, W_SIZE*2, 0, 0, 0);
//update normals pass
glBegin(GL_QUADS);
glTexCoord2f(start,start);glVertex3f(0,0,0);
glTexCoord2f(start,end);glVertex3f(0,1,0);
glTexCoord2f(end,end);glVertex3f(1,1,0);
glTexCoord2f(end,start);glVertex3f(1,0,0);
glEnd();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glFlush();
glDisable(GL_VERTEX_PROGRAM_ARB);
glDisable(GL_FRAGMENT_PROGRAM_ARB);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE2_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE3_ARB);
glBindTexture(GL_TEXTURE_2D,0);
glActiveTextureARB(GL_TEXTURE0_ARB);
unsigned int temp=waveTex1;
waveTex1=waveTex2;
waveTex2=waveTex3;
waveTex3=temp;
}
void CDynWater::DrawHeightTex(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,1,0,1,-1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,waveTex1);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBuffer);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, waveHeight32, 0);
glViewport(0,0,256,256);
int status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
logOutput.Print("FBO not ready4");
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, waveCopyHeightFP );
glEnable( GL_FRAGMENT_PROGRAM_ARB );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, waveCopyHeightVP );
glEnable( GL_VERTEX_PROGRAM_ARB );
camPosX=int(camera->pos.x/W_SIZE);
camPosZ=int(camera->pos.z/W_SIZE);
float startx=(camPosX-120)/1024.0f-(camPosBig.x-WH_SIZE)/WF_SIZE;
float startz=(camPosZ-120)/1024.0f-(camPosBig.z-WH_SIZE)/WF_SIZE;
float endx=(camPosX+120)/1024.0f-(camPosBig.x-WH_SIZE)/WF_SIZE;
float endz=(camPosZ+120)/1024.0f-(camPosBig.z-WH_SIZE)/WF_SIZE;
float startv=8.0f/256;
float endv=248.0f/256;
//update 32 bit height map
glBegin(GL_QUADS);
glTexCoord2f(startx,startz);glVertex3f(startv,startv,0);
glTexCoord2f(startx,endz);glVertex3f(startv,endv,0);
glTexCoord2f(endx,endz);glVertex3f(endv,endv,0);
glTexCoord2f(endx,startz);glVertex3f(endv,startv,0);
glEnd();
glBindTexture(GL_TEXTURE_2D,waveTex1);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glDisable( GL_VERTEX_PROGRAM_ARB );
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glFlush();
}
void CDynWater::AddFrustumRestraint(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-(-10))/c.y);
else
colpoint=cam2->pos-c*((cam2->pos.y-(10))/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 CDynWater::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);
}
}
}
#define WSQUARE_SIZE W_SIZE
static CVertexArray* va;
static inline void DrawVertexA(int x,int y)
{
va->AddVertex0(float3(x*WSQUARE_SIZE,0,y*WSQUARE_SIZE));
}
void CDynWater::DrawWaterSurface(void)
{
int viewRadius=40;
bool inStrip=false;
va=GetVertexArray();
va->Initialize();
camPosBig2.x=floor(max((float)WH_SIZE, min((float)gs->mapx*SQUARE_SIZE-WH_SIZE, (float)camera->pos.x))/(W_SIZE*16))*(W_SIZE*16);
camPosBig2.z=floor(max((float)WH_SIZE, min((float)gs->mapy*SQUARE_SIZE-WH_SIZE, (float)camera->pos.z))/(W_SIZE*16))*(W_SIZE*16);
for(int lod=1;lod<(2<<5);lod*=2){
int cx=(int)(cam2->pos.x/(WSQUARE_SIZE));
int cy=(int)(cam2->pos.z/(WSQUARE_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;
int minty=int(camPosBig2.z/WSQUARE_SIZE-512);
int maxty=int(camPosBig2.z/WSQUARE_SIZE+512);
int mintx=int(camPosBig2.x/WSQUARE_SIZE-512);
int maxtx=int(camPosBig2.x/WSQUARE_SIZE+512);
int minly=cy+(-viewRadius+2-ysquaremod)*lod;
int maxly=cy+(viewRadius-ysquaremod)*lod;
int minlx=cx+(-viewRadius+2-xsquaremod)*lod;
int maxlx=cx+(viewRadius-xsquaremod)*lod;
int xstart=max(minlx,mintx);
int xend=min(maxlx,maxtx);
int ystart=max(minly,minty);
int yend=min(maxly,maxty);
for(int y=ystart;y<yend;y+=lod){
int xs=xstart;
int xe=xend;
int xtest,xtest2;
std::vector<fline>::iterator fli;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -