Пример #1
0
void CFeatureDrawer::Draw()
{
	if(globalRendering->drawFog) {
		glEnable(GL_FOG);
		glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor);
	}

	GML_RECMUTEX_LOCK(feat); // Draw

	CBaseGroundDrawer* gd = readmap->GetGroundDrawer();

	if (gd->DrawExtraTex()) {
		glActiveTextureARB(GL_TEXTURE2_ARB);
		glEnable(GL_TEXTURE_2D);
		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.0f, 0.0f);

		glBindTexture(GL_TEXTURE_2D, gd->infoTex);
		glActiveTextureARB(GL_TEXTURE0_ARB);
	}


	unitDrawer->SetupForUnitDrawing();
	GetVisibleFeatures(0, true);

	for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) {
		opaqueModelRenderers[modelType]->PushRenderState();
		DrawOpaqueFeatures(modelType);
		opaqueModelRenderers[modelType]->PopRenderState();
	}

	unitDrawer->CleanUpUnitDrawing();

	farTextureHandler->Draw();

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

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_FOG);

	DrawFeatureStats();
}
Пример #2
0
void CFeatureDrawer::Draw()
{
	ISky::SetupFog();

	GML_RECMUTEX_LOCK(feat); // Draw

	CBaseGroundDrawer* gd = readMap->GetGroundDrawer();

	if (gd->DrawExtraTex()) {
		glActiveTextureARB(GL_TEXTURE2_ARB);
		glEnable(GL_TEXTURE_2D);
		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);

		glMultiTexCoord4f(GL_TEXTURE2_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen
		SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0.0f, 0.0f);

		glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture());
		glActiveTextureARB(GL_TEXTURE0_ARB);
	}

	unitDrawer->SetupForUnitDrawing(false);
	GetVisibleFeatures(0, true);

	for (int modelType = MODELTYPE_3DO; modelType < MODELTYPE_OTHER; modelType++) {
		opaqueModelRenderers[modelType]->PushRenderState();
		DrawOpaqueFeatures(modelType);
		opaqueModelRenderers[modelType]->PopRenderState();
	}

	unitDrawer->CleanUpUnitDrawing(false);

	farTextureHandler->Draw();

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

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_FOG);
#ifdef USE_GML
	DrawFeatureStats();
#endif
}
Пример #3
0
void CGrassDrawer::EnableShader(const GrassShaderProgram type) {
	CBaseGroundDrawer* gd = readMap->GetGroundDrawer();
	const float3 windSpeed =
		wind.GetCurrentDirection() *
		wind.GetCurrentStrength() *
		mapInfo->grass.bladeWaveScale;

	grassShader = grassShaders[type];
	grassShader->SetFlag("HAVE_INFOTEX", gd->DrawExtraTex());
	grassShader->SetFlag("HAVE_SHADOWS", shadowHandler->shadowsLoaded);
	grassShader->Enable();

	grassShader->SetUniform("frame", gs->frameNum + globalRendering->timeOffset);
	grassShader->SetUniform3v("windSpeed", &windSpeed.x);
	grassShader->SetUniform3v("camPos",    &camera->GetPos().x);
	grassShader->SetUniform3v("camDir",    &camera->forward.x);
	grassShader->SetUniform3v("camUp",     &camera->up.x);
	grassShader->SetUniform3v("camRight",  &camera->right.x);

	grassShader->SetUniform("groundShadowDensity", mapInfo->light.groundShadowDensity);
	grassShader->SetUniformMatrix4x4("shadowMatrix", false, &shadowHandler->shadowMatrix.m[0]);
	grassShader->SetUniform4v("shadowParams", &shadowHandler->GetShadowParams().x);

	grassShader->SetUniform3v("ambientLightColor",  &mapInfo->light.unitAmbientColor.x);
	grassShader->SetUniform3v("diffuseLightColor",  &mapInfo->light.unitSunColor.x);
	grassShader->SetUniform3v("specularLightColor", &mapInfo->light.unitSpecularColor.x);
	grassShader->SetUniform3v("sunDir",             &mapInfo->light.sunDir.x);
}
Пример #4
0
void CGrassDrawer::ResetGlStateNear()
{
	CBaseGroundDrawer* gd = readMap->GetGroundDrawer();

	if (shadowHandler->shadowsLoaded && globalRendering->haveGLSL) {
		grassShader->Disable();

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

		/*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_TEXTURE0_ARB);*/
	} else {
		glActiveTextureARB(GL_TEXTURE1_ARB);
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);

		glActiveTextureARB(GL_TEXTURE2_ARB);
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1);

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

		glActiveTextureARB(GL_TEXTURE0_ARB);
	}

	glDisable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
}
Пример #5
0
void CGrassDrawer::SetupGlStateFar()
{
	assert(globalRendering->haveGLSL);

	CBaseGroundDrawer* gd = readMap->GetGroundDrawer();

	//glEnable(GL_ALPHA_TEST);
	//glAlphaFunc(GL_GREATER, 0.01f);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glDepthMask(GL_FALSE);

	glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glMultMatrixf(camera->GetViewMatrix());
	glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glLoadIdentity();

	EnableShader(GRASS_PROGRAM_DIST);

	glActiveTextureARB(GL_TEXTURE0_ARB);
		glBindTexture(GL_TEXTURE_2D, farTex);
	glActiveTextureARB(GL_TEXTURE1_ARB);
		glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture());
	glActiveTextureARB(GL_TEXTURE2_ARB);
		glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture());
	if (gd->DrawExtraTex()) {
		glActiveTextureARB(GL_TEXTURE3_ARB);
			glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture());
	}
	if (shadowHandler->shadowsLoaded) {
		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_ALPHA);
	}

	glActiveTextureARB(GL_TEXTURE0_ARB);
}
Пример #6
0
void CAdvTreeDrawer::Draw(float treeDistance,bool drawReflection)
{
	int activeFarTex=camera->forward.z<0 ? treeGen->farTex[0] : treeGen->farTex[1];

	bool drawDetailed=true;
	if(treeDistance<4)
		drawDetailed=false;
	if(drawReflection)
		drawDetailed=false;

	CBaseGroundDrawer *gd = readmap->GetGroundDrawer ();

	glEnable(GL_ALPHA_TEST);

	if(gu->drawFog) {
		glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor);
		glEnable(GL_FOG);
	}

	if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
		glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarVP );
		glEnable(GL_VERTEX_PROGRAM_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_ALPHA);

		if(shadowHandler->useFPShadows){
			glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, treeGen->treeFPShadow );
			glEnable( GL_FRAGMENT_PROGRAM_ARB );
			glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,10, mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.z,1);
			glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB,11, 0,0,0,1-mapInfo->light.groundShadowDensity*0.5f);

			glActiveTextureARB(GL_TEXTURE1_ARB);
			glBindTexture(GL_TEXTURE_2D, activeFarTex);
		} else {
			glEnable(GL_TEXTURE_2D);
			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 1-mapInfo->light.groundShadowDensity*0.5f);

			float texConstant[]={mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.z,0.0f};
			glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,texConstant);
			glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_ARB,GL_PREVIOUS_ARB);
			glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_ARB,GL_CONSTANT);
			glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE2_RGB_ARB,GL_TEXTURE);
			glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND2_RGB_ARB,GL_SRC_ALPHA);
			glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_INTERPOLATE_ARB);

			glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB,GL_PREVIOUS_ARB);
			glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_ARB,GL_CONSTANT);
			glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_ADD);

			glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_ARB);

			glActiveTextureARB(GL_TEXTURE1_ARB);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, activeFarTex);
		}
		glActiveTextureARB(GL_TEXTURE0_ARB);

		glMatrixMode(GL_MATRIX0_ARB);
		glLoadMatrixf(shadowHandler->shadowMatrix.m);
		glMatrixMode(GL_MODELVIEW);
	} else {
		glBindTexture(GL_TEXTURE_2D, activeFarTex);
	}
	glEnable(GL_TEXTURE_2D);

	int cx=(int)(camera->pos.x/(SQUARE_SIZE*TREE_SQUARE_SIZE));
	int cy=(int)(camera->pos.z/(SQUARE_SIZE*TREE_SQUARE_SIZE));

	CAdvTreeSquareDrawer drawer;
	drawer.td = this;
	drawer.cx = cx;
	drawer.cy = cy;
	drawer.treeDistance = treeDistance * SQUARE_SIZE * TREE_SQUARE_SIZE;
	drawer.drawDetailed = drawDetailed;

	GML_STDMUTEX_LOCK(tree); // Draw

	// draw far away trees using the map dependent grid visibility
	oldTreeDistance=treeDistance;
	readmap->GridVisibility (camera, TREE_SQUARE_SIZE, drawer.treeDistance * 2.0f, &drawer);

	if(drawDetailed){
		int xstart=std::max(0,cx-2);
		int xend=std::min(gs->mapx/TREE_SQUARE_SIZE-1,cx+2);
		int ystart=std::max(0,cy-2);
		int yend=std::min(gs->mapy/TREE_SQUARE_SIZE-1,cy+2);

		if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
			glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeVP );

			glActiveTextureARB(GL_TEXTURE1_ARB);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);
			glActiveTextureARB(GL_TEXTURE0_ARB);

		} else {
			glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);
			glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeNSVP );
			glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,15, 1.0f/(gs->pwr2mapx*SQUARE_SIZE),1.0f/(gs->pwr2mapy*SQUARE_SIZE),1.0f/(gs->pwr2mapx*SQUARE_SIZE),1);
		}
		glEnable( GL_VERTEX_PROGRAM_ARB );
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13,  camera->right.x,camera->right.y,camera->right.z,0);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9,  camera->up.x,camera->up.y,camera->up.z,0);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,11, mapInfo->light.groundSunColor.x,mapInfo->light.groundSunColor.y,mapInfo->light.groundSunColor.z,0.85f);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,14, mapInfo->light.groundAmbientColor.x,mapInfo->light.groundAmbientColor.y,mapInfo->light.groundAmbientColor.z,0.85f);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,12, 0,0,0,0.20f*(1.0f/MAX_TREE_HEIGHT));	//w=alpha/height modifier
		glAlphaFunc(GL_GREATER,0.5f);
		glDisable(GL_BLEND);
		glColor4f(1,1,1,1);
		va=GetVertexArray();
		va->Initialize();

		struct FadeTree{
			float3 pos;
			float relDist;
			float deltaY;
			int type;
		};
		static FadeTree fadeTrees[3000];
		FadeTree *pFT=fadeTrees;

		for(TreeSquareStruct* pTSS=trees+ystart*treesX; pTSS<=trees+yend*treesX; pTSS+=treesX) {
			for(TreeSquareStruct* tss=pTSS+xstart; tss<=pTSS+xend; ++tss) {
				tss->lastSeen=gs->frameNum;
				va->EnlargeArrays(12*tss->trees.size(),0,VA_SIZE_T); //!alloc room for all tree vertexes
				for(std::map<int,TreeStruct>::iterator ti=tss->trees.begin();ti!=tss->trees.end();++ti){
					TreeStruct* ts=&ti->second;
					float3 pos(ts->pos);
					int type=ts->type;
					float dy;
					unsigned int displist;
					if(type<8){
						dy=0.5f;
						displist=treeGen->pineDL+type;
					} else {
						type-=8;
						dy=0;
						displist=treeGen->leafDL+type;
					}
					if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){
						float camDist=(pos-camera->pos).SqLength();
						if(camDist<SQUARE_SIZE*SQUARE_SIZE*110*110){	//draw detailed tree
							glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0);
							glCallList(displist);
						} else if(camDist<SQUARE_SIZE*SQUARE_SIZE*125*125){	//draw fading tree
							float relDist=(pos.distance(camera->pos)-SQUARE_SIZE*110)/(SQUARE_SIZE*15);
							glAlphaFunc(GL_GREATER,0.8f+relDist*0.2f);
							glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,pos.x,pos.y,pos.z,0);
							glCallList(displist);
							glAlphaFunc(GL_GREATER,0.5f);
							pFT->pos=pos;
							pFT->deltaY=dy;
							pFT->type=type;
							pFT->relDist=relDist;
							++pFT;
						} else {																//draw undetailed tree
							DrawTreeVertex(pos, type*0.125f, dy, false);
						}
					}
				}
			}
		}
		//draw trees that has been marked as falling
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,10,0,0,0,0);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,13,  camera->right.x,camera->right.y,camera->right.z,0);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,9,  camera->up.x,camera->up.y,camera->up.z,0);
		for(std::list<FallingTree>::iterator fti=fallingTrees.begin(); fti!=fallingTrees.end(); ++fti){
			float3 pos=fti->pos-UpVector*(fti->fallPos*20);
			if(camera->InView(pos+float3(0,MAX_TREE_HEIGHT/2,0),MAX_TREE_HEIGHT/2)){
				float ang=fti->fallPos*PI;
				float3 up(fti->dir.x*sin(ang),cos(ang),fti->dir.z*sin(ang));
				float3 z(up.cross(float3(-1,0,0)));
				z.ANormalize();
				float3 x(up.cross(z));
				CMatrix44f transMatrix(pos,x,up,z);

				glPushMatrix();
				glMultMatrixf(&transMatrix[0]);

				int type=fti->type;
				int displist;
				if(type<8){
					displist=treeGen->pineDL+type;
				} else {
					type-=8;
					displist=treeGen->leafDL+type;
				}
				glCallList(displist);

				glPopMatrix();
			}
		}

		glDisable( GL_VERTEX_PROGRAM_ARB );

		if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
			glBindProgramARB( GL_VERTEX_PROGRAM_ARB, treeGen->treeFarVP );
			glEnable(GL_VERTEX_PROGRAM_ARB);

			glActiveTextureARB(GL_TEXTURE1_ARB);
			glBindTexture(GL_TEXTURE_2D, activeFarTex);
			glActiveTextureARB(GL_TEXTURE0_ARB);
		} else {
			glBindTexture(GL_TEXTURE_2D, activeFarTex);
		}
		va->DrawArrayT(GL_QUADS);

		for(FadeTree *pFTree=fadeTrees; pFTree<pFT; ++pFTree) { //faded close trees
			va=GetVertexArray();
			va->Initialize();
			va->CheckInitSize(12*VA_SIZE_T);

			DrawTreeVertex(pFTree->pos, pFTree->type*0.125f, pFTree->deltaY, false);

			glAlphaFunc(GL_GREATER,1-pFTree->relDist*0.5f);
			va->DrawArrayT(GL_QUADS);
		}
	}
	if(shadowHandler->drawShadows && !gd->DrawExtraTex()){
		glDisable( GL_VERTEX_PROGRAM_ARB );
		if(shadowHandler->useFPShadows){
			glDisable(GL_FRAGMENT_PROGRAM_ARB);
		}
		glActiveTextureARB(GL_TEXTURE1_ARB);
		glDisable(GL_TEXTURE_2D);
		glActiveTextureARB(GL_TEXTURE0_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);
	}

	glDisable(GL_FOG);

	glDisable(GL_ALPHA_TEST);

	//clean out squares from memory that are no longer visible
	int startClean=lastListClean*20%(nTrees);
	lastListClean=gs->frameNum;
	int endClean=gs->frameNum*20%(nTrees);

	if(startClean>endClean){
		for(TreeSquareStruct *pTSS=trees+startClean; pTSS<trees+nTrees; ++pTSS) {
			if(pTSS->lastSeen<gs->frameNum-50 && pTSS->displist){
				glDeleteLists(pTSS->displist,1);
				pTSS->displist=0;
			}
			if(pTSS->lastSeenFar<gs->frameNum-50 && pTSS->farDisplist){
				glDeleteLists(pTSS->farDisplist,1);
				pTSS->farDisplist=0;
			}
		}
		for(TreeSquareStruct *pTSS=trees; pTSS<trees+endClean; ++pTSS) {
			if(pTSS->lastSeen<gs->frameNum-50 && pTSS->displist){
				glDeleteLists(pTSS->displist,1);
				pTSS->displist=0;
			}
			if(pTSS->lastSeenFar<gs->frameNum-50 && pTSS->farDisplist){
				glDeleteLists(pTSS->farDisplist,1);
				pTSS->farDisplist=0;
			}
		}
	} else {
		for(TreeSquareStruct *pTSS=trees+startClean; pTSS<trees+endClean; ++pTSS) {
			if(pTSS->lastSeen<gs->frameNum-50 && pTSS->displist){
				glDeleteLists(pTSS->displist,1);
				pTSS->displist=0;
			}
			if(pTSS->lastSeenFar<gs->frameNum-50 && pTSS->farDisplist){
				glDeleteLists(pTSS->farDisplist,1);
				pTSS->farDisplist=0;
			}
		}
	}
}
Пример #7
0
void CAdvTreeDrawer::Draw(float treeDistance, bool drawReflection)
{
	const int activeFarTex = (camera->forward.z < 0.0f)? treeGen->farTex[0]: treeGen->farTex[1];
	const bool drawDetailed = ((treeDistance >= 4.0f) || drawReflection);

	CBaseGroundDrawer* gd = readmap->GetGroundDrawer();
	Shader::IProgramObject* treeShader = NULL;

	#define L mapInfo->light

	glEnable(GL_ALPHA_TEST);
	glEnable(GL_TEXTURE_2D);

	if (globalRendering->drawFog) {
		glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor);
		glEnable(GL_FOG);
	}


	if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) {
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, activeFarTex);
		glActiveTexture(GL_TEXTURE0);
		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_ALPHA);

		treeShader = treeShaders[TREE_PROGRAM_DIST_SHADOW];
		treeShader->Enable();

		if (globalRendering->haveGLSL) {
			treeShader->SetUniformMatrix4fv(7, false, &shadowHandler->shadowMatrix.m[0]);
			treeShader->SetUniform4fv(8, &(shadowHandler->GetShadowParams().x));
		} else {
			treeShader->SetUniformTarget(GL_FRAGMENT_PROGRAM_ARB);
			treeShader->SetUniform4f(10, L.groundAmbientColor.x, L.groundAmbientColor.y, L.groundAmbientColor.z, 1.0f);
			treeShader->SetUniform4f(11, 0.0f, 0.0f, 0.0f, 1.0f - (sky->GetLight()->GetGroundShadowDensity() * 0.5f));
			treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB);

			glMatrixMode(GL_MATRIX0_ARB);
			glLoadMatrixf(shadowHandler->shadowMatrix.m);
			glMatrixMode(GL_MODELVIEW);
		}
	} else {
		glBindTexture(GL_TEXTURE_2D, activeFarTex);
	}


	const int cx = int(camera->pos.x / (SQUARE_SIZE * TREE_SQUARE_SIZE));
	const int cy = int(camera->pos.z / (SQUARE_SIZE * TREE_SQUARE_SIZE));

	CAdvTreeSquareDrawer drawer(this, cx, cy, treeDistance * SQUARE_SIZE * TREE_SQUARE_SIZE, drawDetailed);

	GML_STDMUTEX_LOCK(tree); // Draw

	oldTreeDistance = treeDistance;

	// draw far-trees using map-dependent grid-visibility
	readmap->GridVisibility(camera, TREE_SQUARE_SIZE, drawer.treeDistance * 2.0f, &drawer);


	if (drawDetailed) {
		// draw near-trees
		const int xstart = std::max(                              0, cx - 2);
		const int xend   = std::min(gs->mapx / TREE_SQUARE_SIZE - 1, cx + 2);
		const int ystart = std::max(                              0, cy - 2);
		const int yend   = std::min(gs->mapy / TREE_SQUARE_SIZE - 1, cy + 2);

		if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) {
			treeShader->Disable();
			treeShader = treeShaders[TREE_PROGRAM_NEAR_SHADOW];
			treeShader->Enable();

			if (globalRendering->haveGLSL) {
				treeShader->SetUniformMatrix4fv(7, false, &shadowHandler->shadowMatrix.m[0]);
				treeShader->SetUniform4fv(8, &(shadowHandler->GetShadowParams().x));
			}

			glActiveTexture(GL_TEXTURE1);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);
			glActiveTexture(GL_TEXTURE0);
		} else {
			glBindTexture(GL_TEXTURE_2D, treeGen->barkTex);

			treeShader = treeShaders[TREE_PROGRAM_NEAR_BASIC];
			treeShader->Enable();

			if (!globalRendering->haveGLSL) {
				#define MX (gs->pwr2mapx * SQUARE_SIZE)
				#define MY (gs->pwr2mapy * SQUARE_SIZE)
				treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB);
				treeShader->SetUniform4f(15, 1.0f / MX, 1.0f / MY, 1.0f / MX, 1.0f);
				#undef MX
				#undef MY
			}
		}


		if (globalRendering->haveGLSL) {
			treeShader->SetUniform3fv(0, &camera->right[0]);
			treeShader->SetUniform3fv(1, &camera->up[0]);
			treeShader->SetUniform2f(5, 0.20f * (1.0f / MAX_TREE_HEIGHT), 0.85f);
		} else {
			treeShader->SetUniformTarget(GL_VERTEX_PROGRAM_ARB);
			treeShader->SetUniform3f(13, camera->right.x, camera->right.y, camera->right.z);
			treeShader->SetUniform3f( 9, camera->up.x,    camera->up.y,    camera->up.z   );
			treeShader->SetUniform4f(11, L.groundSunColor.x,     L.groundSunColor.y,     L.groundSunColor.z,     0.85f);
			treeShader->SetUniform4f(14, L.groundAmbientColor.x, L.groundAmbientColor.y, L.groundAmbientColor.z, 0.85f);
			treeShader->SetUniform4f(12, 0.0f, 0.0f, 0.0f, 0.20f * (1.0f / MAX_TREE_HEIGHT)); // w = alpha/height modifier
		}


		glAlphaFunc(GL_GREATER, 0.5f);
		glDisable(GL_BLEND);
		glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

		varr = GetVertexArray();
		varr->Initialize();

		static FadeTree fadeTrees[3000];
		FadeTree* pFT = fadeTrees;


		for (TreeSquareStruct* pTSS = trees + ystart * treesX; pTSS <= trees + yend * treesX; pTSS += treesX) {
			for (TreeSquareStruct* tss = pTSS + xstart; tss <= pTSS + xend; ++tss) {
				tss->lastSeen = gs->frameNum;
				varr->EnlargeArrays(12 * tss->trees.size(), 0, VA_SIZE_T); //!alloc room for all tree vertexes

				for (std::map<int, TreeStruct>::iterator ti = tss->trees.begin(); ti != tss->trees.end(); ++ti) {
					const TreeStruct* ts = &ti->second;
					const float3 pos(ts->pos);

					if (!camera->InView(pos + float3(0.0f, MAX_TREE_HEIGHT / 2.0f, 0.0f), MAX_TREE_HEIGHT / 2.0f)) {
						continue;
					}

					const float camDist = (pos - camera->pos).SqLength();
					int type = ts->type;
					float dy = 0.0f;
					unsigned int displist;

					if (type < 8) {
						dy = 0.5f;
						displist = treeGen->pineDL + type;
					} else {
						type -= 8;
						dy = 0.0f;
						displist = treeGen->leafDL + type;
					}

					if (camDist < (SQUARE_SIZE * SQUARE_SIZE * 110 * 110)) {
						// draw detailed near-distance tree (same as mid-distance trees without alpha)
						treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), pos.x, pos.y, pos.z);
						glCallList(displist);
					} else if (camDist < (SQUARE_SIZE * SQUARE_SIZE * 125 * 125)) {
						// draw mid-distance tree
						const float relDist = (pos.distance(camera->pos) - SQUARE_SIZE * 110) / (SQUARE_SIZE * 15);

						treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), pos.x, pos.y, pos.z);

						glAlphaFunc(GL_GREATER, 0.8f + relDist * 0.2f);
						glCallList(displist);
						glAlphaFunc(GL_GREATER, 0.5f);

						// save for second pass
						pFT->pos = pos;
						pFT->deltaY = dy;
						pFT->type = type;
						pFT->relDist = relDist;
						++pFT;
					} else {
						// draw far-distance tree
						DrawTreeVertex(varr, pos, type * 0.125f, dy, false);
					}
				}
			}
		}


		// reset the world-offset
		treeShader->SetUniform3f(((globalRendering->haveGLSL)? 2: 10), 0.0f, 0.0f, 0.0f);

		// draw trees that have been marked as falling
		for (std::list<FallingTree>::iterator fti = fallingTrees.begin(); fti != fallingTrees.end(); ++fti) {
			const float3 pos = fti->pos - UpVector * (fti->fallPos * 20);

			if (camera->InView(pos + float3(0.0f, MAX_TREE_HEIGHT / 2, 0.0f), MAX_TREE_HEIGHT / 2.0f)) {
				const float ang = fti->fallPos * PI;

				const float3 yvec(fti->dir.x * sin(ang), cos(ang), fti->dir.z * sin(ang));
				const float3 zvec((yvec.cross(float3(-1.0f, 0.0f, 0.0f))).ANormalize());
				const float3 xvec(yvec.cross(zvec));

				CMatrix44f transMatrix(pos, xvec, yvec, zvec);

				glPushMatrix();
				glMultMatrixf(&transMatrix[0]);

				int type = fti->type;
				int displist = 0;

				if (type < 8) {
					displist = treeGen->pineDL + type;
				} else {
					type -= 8;
					displist = treeGen->leafDL + type;
				}

				glCallList(displist);
				glPopMatrix();
			}
		}


		if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) {
			treeShader->Disable();
			treeShader = treeShaders[TREE_PROGRAM_DIST_SHADOW];
			treeShader->Enable();

			glActiveTexture(GL_TEXTURE1);
			glBindTexture(GL_TEXTURE_2D, activeFarTex);
			glActiveTexture(GL_TEXTURE0);
		} else {
			treeShader->Disable();
			glBindTexture(GL_TEXTURE_2D, activeFarTex);
		}


		// draw far-distance trees
		varr->DrawArrayT(GL_QUADS);

		// draw faded mid-distance trees
		for (FadeTree* pFTree = fadeTrees; pFTree < pFT; ++pFTree) {
			varr = GetVertexArray();
			varr->Initialize();
			varr->CheckInitSize(12 * VA_SIZE_T);

			DrawTreeVertex(varr, pFTree->pos, pFTree->type * 0.125f, pFTree->deltaY, false);

			glAlphaFunc(GL_GREATER, 1.0f - (pFTree->relDist * 0.5f));
			varr->DrawArrayT(GL_QUADS);
		}
	}

	if (shadowHandler->shadowsLoaded && !gd->DrawExtraTex()) {
		treeShader->Disable();

		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, 0);
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, 0);
		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);
	} else {
		glBindTexture(GL_TEXTURE_2D, 0);
	}

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_FOG);
	glDisable(GL_ALPHA_TEST);



	// clean out squares from memory that are no longer visible
	const int startClean = lastListClean * 20 % (nTrees);
	const int endClean = gs->frameNum * 20 % (nTrees);

	lastListClean = gs->frameNum;

	if (startClean > endClean) {
		for (TreeSquareStruct* pTSS = trees + startClean; pTSS < trees + nTrees; ++pTSS) {
			if ((pTSS->lastSeen < gs->frameNum - 50) && pTSS->displist) {
				glDeleteLists(pTSS->displist, 1);
				pTSS->displist = 0;
			}
			if ((pTSS->lastSeenFar < gs->frameNum - 50) && pTSS->farDisplist) {
				glDeleteLists(pTSS->farDisplist, 1);
				pTSS->farDisplist = 0;
			}
		}
		for (TreeSquareStruct* pTSS = trees; pTSS < trees + endClean; ++pTSS) {
			if ((pTSS->lastSeen < gs->frameNum - 50) && pTSS->displist) {
				glDeleteLists(pTSS->displist, 1);
				pTSS->displist = 0;
			}
			if ((pTSS->lastSeenFar < gs->frameNum - 50) && pTSS->farDisplist) {
				glDeleteLists(pTSS->farDisplist, 1);
				pTSS->farDisplist = 0;
			}
		}
	} else {
		for (TreeSquareStruct* pTSS = trees + startClean; pTSS < trees + endClean; ++pTSS) {
			if ((pTSS->lastSeen < gs->frameNum - 50) && pTSS->displist) {
				glDeleteLists(pTSS->displist, 1);
				pTSS->displist = 0;
			}
			if ((pTSS->lastSeenFar < gs->frameNum - 50) && pTSS->farDisplist) {
				glDeleteLists(pTSS->farDisplist, 1);
				pTSS->farDisplist = 0;
			}
		}
	}

	#undef L
}
Пример #8
0
void CGrassDrawer::SetupGlStateNear()
{
	CBaseGroundDrawer* gd = readMap->GetGroundDrawer();

	// bind textures
	{
		glActiveTextureARB(GL_TEXTURE0_ARB);
			glBindTexture(GL_TEXTURE_2D, grassBladeTex);
		glActiveTextureARB(GL_TEXTURE1_ARB);
			glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture());
		glActiveTextureARB(GL_TEXTURE2_ARB);
			glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture());
		if (gd->DrawExtraTex()) {
			glActiveTextureARB(GL_TEXTURE3_ARB);
				glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture());
		}
		glActiveTextureARB(GL_TEXTURE5_ARB);
			glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, cubeMapHandler->GetSpecularTextureID());
	}

	// bind shader
	if (globalRendering->haveGLSL) {
		EnableShader(GRASS_PROGRAM_NEAR);

		if (shadowHandler->shadowsLoaded) {
			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_ALPHA);
		}

		glMatrixMode(GL_PROJECTION);
			glPushMatrix();
			glMultMatrixf(camera->GetViewMatrix());
		glMatrixMode(GL_MODELVIEW);
			glPushMatrix();
			glLoadIdentity();
	} else {
		// FPP enable textures
		glActiveTextureARB(GL_TEXTURE0_ARB);
			glEnable(GL_TEXTURE_2D);
		glActiveTextureARB(GL_TEXTURE1_ARB);
			glEnable(GL_TEXTURE_2D);
			glMultiTexCoord4f(GL_TEXTURE1_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen
			SetTexGen(1.0f / (gs->mapx * SQUARE_SIZE), 1.0f / (gs->mapy * SQUARE_SIZE), 0.0f, 0.0f);
		glActiveTextureARB(GL_TEXTURE2_ARB);
			glEnable(GL_TEXTURE_2D);
			glMultiTexCoord4f(GL_TEXTURE2_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen
			SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0.0f, 0.0f);
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
			glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
			glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);
		if (gd->DrawExtraTex()) {
			glActiveTextureARB(GL_TEXTURE3_ARB);
				glEnable(GL_TEXTURE_2D);
				glMultiTexCoord4f(GL_TEXTURE3_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen
				SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0.0f, 0.0f);
				glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
				glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
				glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
				glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
				glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
		}
	}

	glActiveTextureARB(GL_TEXTURE0_ARB);
	glDisable(GL_BLEND);
	glDisable(GL_ALPHA_TEST);
	glDepthMask(GL_TRUE);
	ISky::SetupFog();
}
Пример #9
0
void CFeatureDrawer::Draw()
{
	drawFar.clear();

	if(gu->drawFog) {
		glEnable(GL_FOG);
		glFogfv(GL_FOG_COLOR, mapInfo->atmosphere.fogColor);
	}


	GML_RECMUTEX_LOCK(feat); // Draw

	fadeFeatures.clear();
	fadeFeaturesS3O.clear();

	CBaseGroundDrawer *gd = readmap->GetGroundDrawer();
	if (gd->DrawExtraTex()) {
		glActiveTextureARB(GL_TEXTURE2_ARB);
		glEnable(GL_TEXTURE_2D);
		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);

		glBindTexture(GL_TEXTURE_2D, gd->infoTex);
		glActiveTextureARB(GL_TEXTURE0_ARB);
	}

	unitDrawer->SetupForUnitDrawing();
		unitDrawer->SetupFor3DO();
			DrawRaw(0, &drawFar);
		unitDrawer->CleanUp3DO();
		unitDrawer->DrawQuedS3O();
	unitDrawer->CleanUpUnitDrawing();

	if (drawFar.size()>0) {
		glAlphaFunc(GL_GREATER, 0.5f);
		glEnable(GL_ALPHA_TEST);
		glBindTexture(GL_TEXTURE_2D, fartextureHandler->GetTextureID());
		glColor3f(1.0f, 1.0f, 1.0f);
		glNormal3fv((const GLfloat*) &unitDrawer->camNorm.x);

		CVertexArray* va = GetVertexArray();
		va->Initialize();
		va->EnlargeArrays(drawFar.size() * 4, 0, VA_SIZE_T);
		for (vector<CFeature*>::iterator it = drawFar.begin(); it != drawFar.end(); ++it) {
			fartextureHandler->DrawFarTexture(camera, (*it)->model, (*it)->pos, (*it)->radius, (*it)->heading, va);
		}
		va->DrawArrayT(GL_QUADS);

		glDisable(GL_ALPHA_TEST);
	}

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

	glDisable(GL_TEXTURE_2D);
	glDisable(GL_FOG);

	if(drawStat.size() > 0) {
		if(!water->drawReflection) {
			for (vector<CFeature *>::iterator fi = drawStat.begin(); fi != drawStat.end(); ++fi)
				DrawFeatureStats(*fi);
		}
		drawStat.clear();
	}
}
Пример #10
0
void CGrassDrawer::SetupGlStateFar()
{
	assert(globalRendering->haveGLSL);

	CBaseGroundDrawer* gd = readMap->GetGroundDrawer();

	const float3 windSpeed =
		wind.GetCurrentDirection() *
		wind.GetCurrentStrength() *
		mapInfo->grass.bladeWaveScale;

	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.01f);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glDepthMask(GL_FALSE);

	if (shadowHandler->shadowsLoaded) {
		grassShader = grassShaders[GRASS_PROGRAM_DIST_SHADOW];
		grassShader->SetFlag("HAVE_INFOTEX", gd->DrawExtraTex());
		grassShader->Enable();

		grassShader->SetUniformMatrix4fv(6, false, &shadowHandler->shadowMatrix.m[0]);
		grassShader->SetUniform4fv(7, shadowHandler->GetShadowParams());
		grassShader->SetUniform1f(8, gs->frameNum);
		grassShader->SetUniform3fv(9, &windSpeed.x);
		grassShader->SetUniform3fv(10, &camera->GetPos().x);

		glActiveTextureARB(GL_TEXTURE0_ARB);
			glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture());

		glActiveTextureARB(GL_TEXTURE1_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_ALPHA);
			static const float texConstant[] = {
				mapInfo->light.groundAmbientColor.x * 1.24f,
				mapInfo->light.groundAmbientColor.y * 1.24f,
				mapInfo->light.groundAmbientColor.z * 1.24f,
				1.0f
			};
			glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texConstant);

		glActiveTextureARB(GL_TEXTURE2_ARB);
			glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture());

		glActiveTextureARB(GL_TEXTURE3_ARB);
			glBindTexture(GL_TEXTURE_2D, farTex);

		if (gd->DrawExtraTex()) {
			glActiveTextureARB(GL_TEXTURE4_ARB);
			glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture());
		}

		glActiveTextureARB(GL_TEXTURE0_ARB);
	} else {
		grassShader = grassShaders[GRASS_PROGRAM_DIST_BASIC];
		grassShader->Enable();

		grassShader->SetUniform1f(8, gs->frameNum);
		grassShader->SetUniform3fv(9, &windSpeed.x);
		grassShader->SetUniform3fv(10, &camera->GetPos().x);

		glActiveTextureARB(GL_TEXTURE0_ARB);
		glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture());

		//glActiveTextureARB(GL_TEXTURE1_ARB);

		glActiveTextureARB(GL_TEXTURE2_ARB);
		glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture());

		glActiveTextureARB(GL_TEXTURE3_ARB);
		glBindTexture(GL_TEXTURE_2D, farTex);

		if (gd->DrawExtraTex()) {
			glActiveTextureARB(GL_TEXTURE4_ARB);
			glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture());
		}

		glActiveTextureARB(GL_TEXTURE0_ARB);
	}
}
Пример #11
0
void CGrassDrawer::SetupGlStateNear()
{
	CBaseGroundDrawer* gd = readMap->GetGroundDrawer();

	const float3 windSpeed =
		wind.GetCurrentDirection() *
		wind.GetCurrentStrength() *
		mapInfo->grass.bladeWaveScale;

	if (shadowHandler->shadowsLoaded && globalRendering->haveGLSL) {
		grassShader = grassShaders[GRASS_PROGRAM_NEAR_SHADOW];
		grassShader->SetFlag("HAVE_INFOTEX", gd->DrawExtraTex());
		grassShader->Enable();

		grassShader->SetUniform2f(2, 0.0f, 0.0f);
		grassShader->SetUniformMatrix4fv(6, false, shadowHandler->shadowMatrix);
		grassShader->SetUniform4fv(7, shadowHandler->GetShadowParams());
		grassShader->SetUniform1f(8, gs->frameNum);
		grassShader->SetUniform3fv(9, &windSpeed.x);
		grassShader->SetUniform3fv(10, &camera->GetPos().x);

		glActiveTextureARB(GL_TEXTURE0_ARB);
			glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture());

		glActiveTextureARB(GL_TEXTURE1_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_ALPHA);
			static const float texConstant[] = {
				mapInfo->light.groundAmbientColor.x * 1.24f,
				mapInfo->light.groundAmbientColor.y * 1.24f,
				mapInfo->light.groundAmbientColor.z * 1.24f,
				1.0f
			};
			glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texConstant);

		glActiveTextureARB(GL_TEXTURE2_ARB);
			glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture());

		glActiveTextureARB(GL_TEXTURE3_ARB);
			glBindTexture(GL_TEXTURE_2D, grassBladeTex);

		if (gd->DrawExtraTex()) {
			glActiveTextureARB(GL_TEXTURE4_ARB);
			glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture());
		}

		glActiveTextureARB(GL_TEXTURE0_ARB);

		if (!globalRendering->haveGLSL) {
			glActiveTextureARB(GL_TEXTURE1_ARB);
			glEnable(GL_TEXTURE_2D);
			glActiveTextureARB(GL_TEXTURE2_ARB);
			glEnable(GL_TEXTURE_2D);
			glActiveTextureARB(GL_TEXTURE3_ARB);
			glEnable(GL_TEXTURE_2D);
			if (gd->DrawExtraTex()) {
				glActiveTextureARB(GL_TEXTURE4_ARB);
				glEnable(GL_TEXTURE_2D);
			}
			glActiveTextureARB(GL_TEXTURE0_ARB);
			glEnable(GL_TEXTURE_2D);
		}

		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glMultMatrixf(camera->GetViewMatrix());
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glLoadIdentity();
	} else {
		glActiveTextureARB(GL_TEXTURE0_ARB);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, grassBladeTex);

		glActiveTextureARB(GL_TEXTURE1_ARB);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, readMap->GetGrassShadingTexture());
			glMultiTexCoord4f(GL_TEXTURE1_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen
			SetTexGen(1.0f / (gs->mapx * SQUARE_SIZE), 1.0f / (gs->mapy * SQUARE_SIZE), 0.0f, 0.0f);

		glActiveTextureARB(GL_TEXTURE2_ARB);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, readMap->GetShadingTexture());

		glMultiTexCoord4f(GL_TEXTURE2_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen
			SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0.0f, 0.0f);

			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
			glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
			glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);

		if (gd->DrawExtraTex()) {
			glActiveTextureARB(GL_TEXTURE3_ARB);
			glEnable(GL_TEXTURE_2D);
			glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB);
			glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
			glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);

			glMultiTexCoord4f(GL_TEXTURE3_ARB, 1.0f,1.0f,1.0f,1.0f); // workaround a nvidia bug with TexGen
			SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0.0f, 0.0f);

			glBindTexture(GL_TEXTURE_2D, gd->GetActiveInfoTexture());
			glActiveTextureARB(GL_TEXTURE0_ARB);
		}

		glActiveTextureARB(GL_TEXTURE0_ARB);
	}

	glDisable(GL_BLEND);
	glDisable(GL_ALPHA_TEST);
	glDepthMask(GL_TRUE);

	ISky::SetupFog();
}
Пример #12
0
void CGroundDecalHandler::Draw(void)
{
	if (!drawDecals) {
		return;
	}

	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(-10, -200);
	glDepthMask(0);

	glActiveTextureARB(GL_TEXTURE1_ARB);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, readmap->GetShadingTexture());
		SetTexGen(1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0, 0);
		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
	CBaseGroundDrawer *gd = readmap->GetGroundDrawer();
	if (gd->DrawExtraTex()) {
			glActiveTextureARB(GL_TEXTURE3_ARB);
			glEnable(GL_TEXTURE_2D);
			glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_ARB,GL_ADD_SIGNED_ARB);
			glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_ARB,GL_MODULATE);
			glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_ARB,GL_PREVIOUS_ARB);
			glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_ARB,GL_TEXTURE);
			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);

			glBindTexture(GL_TEXTURE_2D, gd->infoTex);
	}
	glActiveTextureARB(GL_TEXTURE0_ARB);


	if (shadowHandler && shadowHandler->drawShadows) {
		glActiveTextureARB(GL_TEXTURE2_ARB);
			glEnable(GL_TEXTURE_2D);
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
			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 (readmap->GetShadingTexture() == 0) {
			glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, decalFPsm3);
		} else {
			// also used for SM3 maps with baked lighting
			glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, decalFPsmf);
		}
		glEnable(GL_FRAGMENT_PROGRAM_ARB);
		glBindProgramARB(GL_VERTEX_PROGRAM_ARB, decalVP);
		glEnable(GL_VERTEX_PROGRAM_ARB);

		const float3 ac = mapInfo->light.groundAmbientColor * (210.0f / 255.0f);

		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 10, 1.0f / (gs->pwr2mapx * SQUARE_SIZE), 1.0f / (gs->pwr2mapy * SQUARE_SIZE), 0, 1);
		glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 10, ac.x, ac.y, ac.z, 1);
		glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 11, 0, 0, 0, mapInfo->light.groundShadowDensity);
		glMatrixMode(GL_MATRIX0_ARB);
		glLoadMatrixf(shadowHandler->shadowMatrix.m);
		glMatrixMode(GL_MODELVIEW);
	}

	// create and draw the quads for each building decal
	for (std::vector<BuildingDecalType*>::iterator bdti = buildingDecalTypes.begin(); bdti != buildingDecalTypes.end(); ++bdti) {
		BuildingDecalType* bdt = *bdti;

		if (!bdt->buildingDecals.empty()) {

			glBindTexture(GL_TEXTURE_2D, bdt->texture);

			decalsToDraw.clear();
			{
				GML_STDMUTEX_LOCK(decal); // Draw

				set<BuildingGroundDecal*>::iterator bgdi = bdt->buildingDecals.begin();

				while (bgdi != bdt->buildingDecals.end()) {
					BuildingGroundDecal* decal = *bgdi;

					if (decal->owner && decal->owner->buildProgress >= 0) {
						decal->alpha = decal->owner->buildProgress;
					} else if (!decal->gbOwner) {
						decal->alpha -= decal->alphaFalloff * globalRendering->lastFrameTime * gs->speedFactor;
					}

					if (decal->alpha < 0.0f) {
						// make sure RemoveBuilding() won't try to modify this decal
						if (decal->owner) {
							decal->owner->buildingDecal = 0;
						}

						delete decal;

						set<BuildingGroundDecal*>::iterator next(bgdi); ++next;
						bdt->buildingDecals.erase(bgdi);
						bgdi = next;

						continue;
					}

					if (!decal->owner || (decal->owner->losStatus[gu->myAllyTeam] & (LOS_INLOS | LOS_PREVLOS)) || gu->spectatingFullView) {
						decalsToDraw.push_back(decal);
					}

					bgdi++;
				}
			}

			for(std::vector<BuildingGroundDecal*>::iterator di = decalsToDraw.begin(); di != decalsToDraw.end(); ++di) {
				BuildingGroundDecal *decal = *di;
				if (camera->InView(decal->pos, decal->radius)) {
					DrawBuildingDecal(decal);
				}
			}

			//glBindTexture(GL_TEXTURE_2D, 0);
		}
	}


	if (shadowHandler && shadowHandler->drawShadows) {
		glDisable(GL_FRAGMENT_PROGRAM_ARB);
		glDisable(GL_VERTEX_PROGRAM_ARB);

		glActiveTextureARB(GL_TEXTURE2_ARB);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
			glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
			glDisable(GL_TEXTURE_2D);
		glActiveTextureARB(GL_TEXTURE1_ARB);

		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);

		glActiveTextureARB(GL_TEXTURE0_ARB);
	}

	glPolygonOffset(-10, -20);

	unsigned char color[4] = {255, 255, 255, 255};
	unsigned char color2[4] = {255, 255, 255, 255};

	{
		GML_STDMUTEX_LOCK(track); // Draw
		// Delayed addition of new tracks
		for (std::vector<TrackToAdd>::iterator ti = tracksToBeAdded.begin(); ti != tracksToBeAdded.end(); ++ti) {
			TrackToAdd *tta = &(*ti);
			if(tta->ts->owner == NULL) {
				delete tta->tp;
				if(tta->unit == NULL)
					tracksToBeDeleted.push_back(tta->ts);
				continue; // unit removed
			}

			CUnit *unit = tta->unit;
			if(unit == NULL) {
				unit = tta->ts->owner;
				trackTypes[unit->unitDef->trackType]->tracks.insert(tta->ts);
			}

			TrackPart *tp = tta->tp;
			//if the unit is moving in a straight line only place marks at half the rate by replacing old ones
			bool replace = false;
			if(unit->myTrack->parts.size()>1) {
				list<TrackPart *>::iterator pi = --unit->myTrack->parts.end();
				list<TrackPart *>::iterator pi2 = pi--;
				if(((tp->pos1+(*pi)->pos1)*0.5f).SqDistance((*pi2)->pos1)<1)
					replace = true;
			}
			if(replace) {
				delete unit->myTrack->parts.back();
				unit->myTrack->parts.back() = tp;
			}
			else {
				unit->myTrack->parts.push_back(tp);
			}
		}
		tracksToBeAdded.clear();
	}

	for (std::vector<UnitTrackStruct *>::iterator ti = tracksToBeDeleted.begin(); ti != tracksToBeDeleted.end(); ++ti) {
		delete *ti;
	}
	tracksToBeDeleted.clear();

	tracksToBeCleaned.clear();

	// create and draw the unit footprint quads
	for (std::vector<TrackType*>::iterator tti = trackTypes.begin(); tti != trackTypes.end(); ++tti) {
		TrackType* tt = *tti;
		if (!tt->tracks.empty()) {
			set<UnitTrackStruct*>::iterator utsi = tt->tracks.begin();

			CVertexArray* va = GetVertexArray();
			va->Initialize();
			glBindTexture(GL_TEXTURE_2D, tt->texture);

			while (utsi != tt->tracks.end()) {
				UnitTrackStruct* track = *utsi;
				if (track->parts.empty()) {
					tracksToBeCleaned.push_back(TrackToClean(track, &(tt->tracks)));
					continue;
				}
				if (track->parts.front()->creationTime < gs->frameNum - track->lifeTime) {
					tracksToBeCleaned.push_back(TrackToClean(track, &(tt->tracks)));
				}
				if (camera->InView((track->parts.front()->pos1 + track->parts.back()->pos1) * 0.5f, track->parts.front()->pos1.distance(track->parts.back()->pos1) + 500)) {
					list<TrackPart *>::iterator ppi = track->parts.begin();
					color2[3] = std::max(0, track->trackAlpha - (int) ((gs->frameNum - (*ppi)->creationTime) * track->alphaFalloff));

					va->EnlargeArrays(track->parts.size()*4,0,VA_SIZE_TC);
					for (list<TrackPart *>::iterator pi = ++track->parts.begin(); pi != track->parts.end(); ++pi) {
						color[3] = std::max(0, track->trackAlpha - (int) ((gs->frameNum - (*ppi)->creationTime) * track->alphaFalloff));
						if ((*pi)->connected) {
							va->AddVertexQTC((*ppi)->pos1, (*ppi)->texPos, 0, color2);
							va->AddVertexQTC((*ppi)->pos2, (*ppi)->texPos, 1, color2);
							va->AddVertexQTC((*pi)->pos2, (*pi)->texPos, 1, color);
							va->AddVertexQTC((*pi)->pos1, (*pi)->texPos, 0, color);
						}
						color2[3] = color[3];
						ppi = pi;
					}
				}
				utsi++;
			}
			va->DrawArrayTC(GL_QUADS);
		}
	}

	{
		GML_STDMUTEX_LOCK(track); // Draw
		// Cleanup old tracks
		for (std::vector<TrackToClean>::iterator ti = tracksToBeCleaned.begin(); ti != tracksToBeCleaned.end(); ++ti) {
			TrackToClean *ttc = &(*ti);
			UnitTrackStruct *track = ttc->track;
			while (!track->parts.empty() && track->parts.front()->creationTime < gs->frameNum - track->lifeTime) {
				delete track->parts.front();
				track->parts.pop_front();
			}
			if (track->parts.empty()) {
				if (track->owner) {
					track->owner->myTrack = 0;
					track->owner = 0;
				}
				ttc->tracks->erase(track);
				tracksToBeDeleted.push_back(track);
			}
		}
	}

	glBindTexture(GL_TEXTURE_2D, scarTex);
	glPolygonOffset(-10, -400);

	scarsToBeChecked.clear();
	{
		GML_STDMUTEX_LOCK(scar); // Draw

		for (std::vector<Scar*>::iterator si = scarsToBeAdded.begin(); si != scarsToBeAdded.end(); ++si)
			scarsToBeChecked.push_back(*si);

		scarsToBeAdded.clear();
	}

	for (std::vector<Scar*>::iterator si = scarsToBeChecked.begin(); si != scarsToBeChecked.end(); ++si) {
		Scar* s = *si;
		TestOverlaps(s);

		int x1 = s->x1 / 16;
		int x2 = min(scarFieldX - 1, s->x2 / 16);
		int y1 = s->y1 / 16;
		int y2 = min(scarFieldY - 1, s->y2 / 16);

		for (int y = y1; y <= y2; ++y) {
			for (int x = x1; x <= x2; ++x) {
				std::set<Scar*>* quad = &scarField[y * scarFieldX + x];
				quad->insert(s);
			}
		}

		scars.push_back(s); 
	}

	// create and draw the 16x16 quads for each ground scar
	for (std::list<Scar*>::iterator si = scars.begin(); si != scars.end(); ) {
		Scar* scar = *si;

		if (scar->lifeTime < gs->frameNum) {
			RemoveScar(*si, false);
			si = scars.erase(si);
			continue;
		}

		if (camera->InView(scar->pos, scar->radius + 16)) {
			DrawGroundScar(scar, groundScarAlphaFade);
		}

		++si;
	}


	glDisable(GL_POLYGON_OFFSET_FILL);
	glDisable(GL_BLEND);

	glActiveTextureARB(GL_TEXTURE1_ARB);
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);
		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glActiveTextureARB(GL_TEXTURE3_ARB); //! infotex
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);
		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glActiveTextureARB(GL_TEXTURE0_ARB);
}