⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dynwater.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			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 + -