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

📄 grassdrawer.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	const int blockMapSize=grassSquareSize*grassBlockSize;

	CGrassBlockDrawer drawer;

	drawer.cx=(int)(camera->pos.x/(SQUARE_SIZE*blockMapSize));
	drawer.cy=(int)(camera->pos.z/(SQUARE_SIZE*blockMapSize));
	drawer.gd = this;

	readmap->GridVisibility (camera, blockMapSize, maxGrassDist, &drawer);
	CVertexArray *va = drawer.va;
	
	float grassDistance=maxGrassDist;

	std::sort(drawer.inviewGrass.begin(),drawer.inviewGrass.end(),GrassSort);
	std::sort(drawer.inviewNearGrass.begin(),drawer.inviewNearGrass.end(),GrassSortNear);
	
	glEnable(GL_BLEND);
	glEnable(GL_ALPHA_TEST);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	glEnable( GL_VERTEX_PROGRAM_ARB );
	glAlphaFunc(GL_GREATER,0.01f);
	glDepthMask(false);

	if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
		glActiveTextureARB(GL_TEXTURE3_ARB);
		glBindTexture(GL_TEXTURE_2D, farTex);
		glActiveTextureARB(GL_TEXTURE0_ARB);

		glMatrixMode(GL_PROJECTION);
		glPopMatrix();
		glMatrixMode(GL_MODELVIEW);
		glPopMatrix();

		glBindProgramARB( GL_VERTEX_PROGRAM_ARB, grassFarVP );
	} else {
		glBindProgramARB( GL_VERTEX_PROGRAM_ARB, grassFarNSVP );
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12,  1.0f/(gs->mapx*SQUARE_SIZE),1.0f/(gs->mapy*SQUARE_SIZE),0,1);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13,  1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),0,1);
		glBindTexture(GL_TEXTURE_2D, farTex);

		if(gd->DrawExtraTex()){
			glActiveTextureARB(GL_TEXTURE3_ARB);
			glDisable(GL_TEXTURE_GEN_S);
			glDisable(GL_TEXTURE_GEN_T);
			glActiveTextureARB(GL_TEXTURE0_ARB);
		}
		glActiveTextureARB(GL_TEXTURE1_ARB);
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);
		glActiveTextureARB(GL_TEXTURE2_ARB);
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);
		glActiveTextureARB(GL_TEXTURE0_ARB);
	}

	for(std::vector<InviewGrass*>::iterator gi=drawer.inviewGrass.begin();gi!=drawer.inviewGrass.end();++gi){
		if((*gi)->dist+128<grassDistance)
			glColor4f(0.62f,0.62f,0.62f,1);			
		else
			glColor4f(0.62f,0.62f,0.62f,1-((*gi)->dist+128-grassDistance)/128.0f);			

		float3 v=grass[(*gi)->num].pos-camera->pos;
		v.Normalize();
		float3 side(v.cross(UpVector));
		side.Normalize();
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,8,  side.x,side.y,side.z,0);
		float3 up(side.cross(v));
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9,  up.x,up.y,up.z,0);
		float ang=acos(v.y);
		int texPart=min(15,(int)max(0,(int)((ang+PI/16-PI/2)/PI*30)));
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10, texPart/16.0f,0,0,0.0f);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11,  -v.x,-v.y,-v.z,0);
		grass[(*gi)->num].va->DrawArrayTN(GL_QUADS);
		delete *gi;	
	}
	glColor4f(0.62f,0.62f,0.62f,1);			
	for(std::vector<InviewNearGrass*>::iterator gi=drawer.inviewNearGrass.begin();gi!=drawer.inviewNearGrass.end();++gi){
		int x=(*gi)->x;
		int y=(*gi)->y;
		if(grassMap[(y)*gs->mapx/grassSquareSize+(x)]){

			float3 squarePos((x+0.5f)*SQUARE_SIZE*grassSquareSize, 0, (y+0.5f)*SQUARE_SIZE*grassSquareSize);
			squarePos.y=ground->GetHeight2(squarePos.x,squarePos.z);
			float3 v=squarePos-camera->pos;
			v.Normalize();
			float3 side(v.cross(UpVector));
			side.Normalize();
			glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,8,  side.x,side.y,side.z,0);
			float3 up(side.cross(v));
			glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9,  up.x,up.y,up.z,0);
			float ang=acos(v.y);
			int texPart=min(15,int(max(0,int((ang+PI/16-PI/2)/PI*30))));
			glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10, texPart/16.0f,0,0,0.0f);
			glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11,  -v.x,-v.y,-v.z,0);

			srand(y*1025+x);
			rand();
			rand();
			int numGrass=numTurfs;
			va=GetVertexArray();
			va->Initialize();
			for(int a=0;a<numGrass;a++){
				float dx=(x+fRand(1))*SQUARE_SIZE*grassSquareSize;
				float dy=(y+fRand(1))*SQUARE_SIZE*grassSquareSize;
				float3 pos(dx,ground->GetHeight2(dx,dy)+0.5f,dy);
				pos.y-=ground->GetSlope(dx,dy)*10+0.03f;
				float col=1;
				if(camera->InView(pos,turfSize*0.7f)){
					va->AddVertexTN(pos,0,0,float3(-turfSize*0.6f,-turfSize*0.6f,col));
					va->AddVertexTN(pos,1/16.0f,0,float3(turfSize*0.6f,-turfSize*0.6f,col));
					va->AddVertexTN(pos,1/16.0f,1,float3(turfSize*0.6f,turfSize*0.6f,col));
					va->AddVertexTN(pos,0,1,float3(-turfSize*0.6f,turfSize*0.6f,col));
				}
			}
			va->DrawArrayTN(GL_QUADS);
		}
		delete *gi;	
	}

	//cleanup stuff
	glDisable( GL_VERTEX_PROGRAM_ARB );
	glDepthMask(true);
	glEnable(GL_FOG);
	glDisable(GL_ALPHA_TEST);

	if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
		glActiveTextureARB(GL_TEXTURE0_ARB);
		glTexEnvi(GL_TEXTURE_ENV,GL_RGB_SCALE_ARB,1);
		glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
		glActiveTextureARB(GL_TEXTURE1_ARB);
		glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
		glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
		glActiveTextureARB(GL_TEXTURE3_ARB);
		glDisable(GL_TEXTURE_2D);
		glActiveTextureARB(GL_TEXTURE0_ARB);
	}

	if(gd->DrawExtraTex()){
		glActiveTextureARB(GL_TEXTURE3_ARB);
		glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
		glDisable(GL_TEXTURE_2D);
		glActiveTextureARB(GL_TEXTURE0_ARB);
	}

	glActiveTextureARB(GL_TEXTURE1_ARB);
	glDisable(GL_TEXTURE_2D);
	glActiveTextureARB(GL_TEXTURE2_ARB);
	glDisable(GL_TEXTURE_2D);
	glTexEnvi(GL_TEXTURE_ENV,GL_RGB_SCALE_ARB,1);
	glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
	glActiveTextureARB(GL_TEXTURE0_ARB);


	int startClean=lastListClean*20%(32*32);
	lastListClean=gs->frameNum;
	int endClean=gs->frameNum*20%(32*32);
	if(startClean>endClean){
		for(int a=startClean;a<32*32;a++){
			if(grass[a].lastSeen<gs->frameNum-50 && grass[a].va){
				delete grass[a].va;
				grass[a].va=0;
			}
		}
		for(int a=0;a<endClean;a++){
			if(grass[a].lastSeen<gs->frameNum-50 && grass[a].va){
				delete grass[a].va;
				grass[a].va=0;
			}
		}
	} else {
		for(int a=startClean;a<endClean;a++){
			if(grass[a].lastSeen<gs->frameNum-50 && grass[a].va){
				delete grass[a].va;
				grass[a].va=0;
			}
		}
	}
}

void CGrassDrawer::ResetPos(const float3& pos)
{
	if(grassOff)
		return;
	int a=(int(pos.z/(SQUARE_SIZE*grassSquareSize*grassBlockSize))&31)*32+(int(pos.x/(SQUARE_SIZE*grassSquareSize*grassBlockSize))&31);
	if(grass[a].va){
		delete grass[a].va;
		grass[a].va=0;
	}
	grass[a].square=-1;
}

void CGrassDrawer::CreateGrassDispList(int listNum)
{
	CVertexArray* va=GetVertexArray();
	va->Initialize();


	for(int a=0;a<strawPerTurf;++a){
		float maxAng=fRand(PI/2);
		float3 sideVect(fRand(1)-0.5f,0,fRand(1)-0.5f);
		sideVect.Normalize();
		float3 forwardVect=sideVect.cross(UpVector);
		sideVect*=0.32f;

		float3 basePos(30,0,30);
		while(basePos.SqLength2D()>turfSize*turfSize/4)
			basePos=float3(fRand(turfSize)-turfSize*0.5f,0,fRand(turfSize)-turfSize*0.5f);

		float length=4+fRand(4);

		int tex=(int)fRand(15.9999f);
		float xtexBase=tex*(1/16.0f);
		int numSections=1+(int)(maxAng*5);
		for(int b=0;b<numSections;++b){
			float h=b*(1.0f/numSections);
			float ang=maxAng*h;
			if(b==0){
				va->AddVertexT(basePos+sideVect*(1-h)+(UpVector*cos(ang)+forwardVect*sin(ang))*length*h-float3(0,0.1f,0), xtexBase, h);
				va->AddVertexT(basePos+sideVect*(1-h)+(UpVector*cos(ang)+forwardVect*sin(ang))*length*h-float3(0,0.1f,0), xtexBase, h);
			} else {
				va->AddVertexT(basePos+sideVect*(1-h)+(UpVector*cos(ang)+forwardVect*sin(ang))*length*h, xtexBase, h);
			}
			va->AddVertexT(basePos-sideVect*(1-h)+(UpVector*cos(ang)+forwardVect*sin(ang))*length*h, xtexBase+1.0f/16, h);
		}
		va->AddVertexT(basePos+(UpVector*cos(maxAng)+forwardVect*sin(maxAng))*length, xtexBase+1.0f/32, 1);
		va->AddVertexT(basePos+(UpVector*cos(maxAng)+forwardVect*sin(maxAng))*length, xtexBase+1.0f/32, 1);
	}

	glNewList(listNum,GL_COMPILE);
	va->DrawArrayT(GL_TRIANGLE_STRIP);
	glEndList();
}

void CGrassDrawer::CreateGrassBladeTex(unsigned char* buf)
{
	float3 col(0.59f+fRand(0.11f),0.81f+fRand(0.08f),0.57f+fRand(0.11f));
	for(int y=0;y<64;++y){
		for(int x=0;x<16;++x){
			buf[(y*256+x)*4+0]=(unsigned char) ((col.x+y*0.0005f+fRand(0.05f))*255);
			buf[(y*256+x)*4+1]=(unsigned char) ((col.y+y*0.0006f+fRand(0.05f))*255);
			buf[(y*256+x)*4+2]=(unsigned char) ((col.z+y*0.0004f+fRand(0.05f))*255);
			buf[(y*256+x)*4+3]=1;
		}
	}
	for(int y=0;y<64;++y){
		for(int x=7;x<9;++x){
			buf[(y*256+x)*4+0]=(unsigned char) ((col.x+y*0.0005f+fRand(0.05f)-0.03f)*255);
			buf[(y*256+x)*4+1]=(unsigned char) ((col.y+y*0.0006f+fRand(0.05f)-0.03f)*255);
			buf[(y*256+x)*4+2]=(unsigned char) ((col.z+y*0.0004f+fRand(0.05f)-0.03f)*255);
		}
	}
	for(int y=4;y<64;y+=4+(int)fRand(3)){
		for(int a=0;a<7 && a+y<64;++a){
			buf[((a+y)*256+a+9)*4+0]=(unsigned char) ((col.x+y*0.0005f+fRand(0.05f)-0.03f)*255);
			buf[((a+y)*256+a+9)*4+1]=(unsigned char) ((col.y+y*0.0006f+fRand(0.05f)-0.03f)*255);
			buf[((a+y)*256+a+9)*4+2]=(unsigned char) ((col.z+y*0.0004f+fRand(0.05f)-0.03f)*255);

			buf[((a+y)*256+6-a)*4+0]=(unsigned char) ((col.x+y*0.0005f+fRand(0.05f)-0.03f)*255);
			buf[((a+y)*256+6-a)*4+1]=(unsigned char) ((col.y+y*0.0006f+fRand(0.05f)-0.03f)*255);
			buf[((a+y)*256+6-a)*4+2]=(unsigned char) ((col.z+y*0.0004f+fRand(0.05f)-0.03f)*255);
		}
	}

/*	for(int y=0;y<64;++y){
		for(int x=0;x<16;++x){
			buf[(y*256+x)*4+0]=255;
			buf[(y*256+x)*4+1]=255;
			buf[(y*256+x)*4+2]=255;
			buf[(y*256+x)*4+3]=1;
		}
	}*/
}

void CGrassDrawer::CreateFarTex(void)
{
	int sizeMod=2;
	unsigned char* buf=SAFE_NEW unsigned char[64*sizeMod*1024*sizeMod*4];
	unsigned char* buf2=SAFE_NEW unsigned char[256*sizeMod*256*sizeMod*4];
	memset(buf,0,64*sizeMod*1024*sizeMod*4);
	memset(buf2,0,256*sizeMod*256*sizeMod*4);

	glPushMatrix();
	glLoadIdentity();
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();

	glEnable(GL_TEXTURE_2D);
	glDisable(GL_BLEND);
	glDisable(GL_ALPHA_TEST);
	glBindTexture(GL_TEXTURE_2D, grassBladeTex);
	glEnable(GL_TEXTURE_2D);
	glDisable(GL_FOG);
	glDisable(GL_BLEND);
	glColor4f(1,1,1,1);			
	glViewport(0,0,256*sizeMod,256*sizeMod);

	for(int a=0;a<16;++a){
		glClearColor(0.0f,0.0f,0.0f,0);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glRotatef((a-1)*90/15.0f,1,0,0);
		glTranslatef(0,-0.5f,0);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		glOrtho(-turfSize*0.6f, turfSize*0.6f, -turfSize*0.6f, turfSize*0.6f, -turfSize, turfSize);

		glCallList(grassDL);
		
		glReadPixels(0,0,256*sizeMod,256*sizeMod,GL_RGBA,GL_UNSIGNED_BYTE,buf2);

//		CBitmap bm(buf2,512,512);
//		bm.Save("ft.bmp");

		int dx=a*64*sizeMod;
		for(int y=0;y<64*sizeMod;++y){
			for(int x=0;x<64*sizeMod;++x){
				float r=0,g=0,b=0,a=0;
				for(int y2=0;y2<4;++y2){
					for(int x2=0;x2<4;++x2){
						if(buf2[((y*4+y2)*256*sizeMod+x*4+x2)*4]==0 && buf2[((y*4+y2)*256*sizeMod+x*4+x2)*4+1]==0 && buf2[((y*4+y2)*256*sizeMod+x*4+x2)*4+2]==0){
						} else {
							float s=1;
							if(y!=0 && y!=64*sizeMod-1 && (buf2[((y*4+y2)*256*sizeMod+x*4+x2+1)*4+1]==0 || buf2[((y*4+y2)*256*sizeMod+x*4+x2-1)*4+1]==0 || buf2[((y*4+y2+1)*256*sizeMod+x*4+x2)*4+1]==0 || buf2[((y*4+y2-1)*256*sizeMod+x*4+x2)*4+1]==0)){
								s=0.5f;
							}
							r+=s*buf2[((y*4+y2)*256*sizeMod+x*4+x2)*4+0];
							g+=s*buf2[((y*4+y2)*256*sizeMod+x*4+x2)*4+1];
							b+=s*buf2[((y*4+y2)*256*sizeMod+x*4+x2)*4+2];
							a+=s;
						}
					}
				}
				if(a==0){
					buf[((y)*1024*sizeMod+x+dx)*4+0]=190;
					buf[((y)*1024*sizeMod+x+dx)*4+1]=230;
					buf[((y)*1024*sizeMod+x+dx)*4+2]=190;
					buf[((y)*1024*sizeMod+x+dx)*4+3]=0;
				} else {
					buf[((y)*1024*sizeMod+x+dx)*4+0]=(unsigned char) (r/a);
					buf[((y)*1024*sizeMod+x+dx)*4+1]=(unsigned char) (g/a);
					buf[((y)*1024*sizeMod+x+dx)*4+2]=(unsigned char) (b/a);
					buf[((y)*1024*sizeMod+x+dx)*4+3]=(unsigned char) (min((float)255,a*16));
				}
			}
		}
	}
//	CBitmap bm(buf,1024*sizeMod,64*sizeMod);
//	bm.Save("fartex.bmp");

	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

	glGenTextures(1, &farTex);
	glBindTexture(GL_TEXTURE_2D, farTex);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
	gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,1024*sizeMod, 64*sizeMod, GL_RGBA, GL_UNSIGNED_BYTE, buf);

	delete[] buf;
	delete[] buf2;
}

void CGrassDrawer::AddGrass(float3 pos)
{
	if(grassOff)
		return;
	grassMap[(int(pos.z)/SQUARE_SIZE/grassSquareSize)*gs->mapx/grassSquareSize+int(pos.x)/SQUARE_SIZE/grassSquareSize]=1;
}

void CGrassDrawer::RemoveGrass(int x, int z)
{
	if(grassOff)
		return;
	grassMap[(z/grassSquareSize)*gs->mapx/grassSquareSize+x/grassSquareSize]=0;
	ResetPos(float3(x*SQUARE_SIZE,0,z*SQUARE_SIZE));
}

void CGrassDrawer::SetTexGen(float scalex,float scaley, float offsetx, float offsety)
{
	GLfloat plan[]={scalex,0,0,offsetx};
	glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
	glTexGenfv(GL_S,GL_EYE_PLANE,plan);
	glEnable(GL_TEXTURE_GEN_S);
	GLfloat plan2[]={0,0,scaley,offsety};
	glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
	glTexGenfv(GL_T,GL_EYE_PLANE,plan2);
	glEnable(GL_TEXTURE_GEN_T);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -