Beispiel #1
0
void CShadowHandler::CreateShadows(void)
{
	fb.Bind();

	glDisable(GL_BLEND);
	glDisable(GL_LIGHTING);
	glDisable(GL_ALPHA_TEST);
	glDisable(GL_TEXTURE_2D);

	glShadeModel(GL_FLAT);
	glColor4f(1, 1, 1, 1);
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

	glViewport(0,0,shadowMapSize,shadowMapSize);

	//glClearColor(0, 0, 0, 0);
	//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClear(GL_DEPTH_BUFFER_BIT);

	firstDraw=false;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0,1,0,1,0,-1);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	float3 sundir=mapInfo->light.sunDir;
	cross1=(sundir.cross(UpVector)).ANormalize();
	cross2=cross1.cross(sundir);
	centerPos=camera->pos;
//	centerPos.x=((int)((centerPos.x+4)/8))*8;
//	centerPos.y=((int)((centerPos.y+4)/8))*8;
//	centerPos.z=((int)((centerPos.z+4)/8))*8;
//	centerPos.y=(ground->GetHeight(centerPos.x,centerPos.z));

	CalcMinMaxView();

	//it should be possible to tweak a bit more shadow map resolution from this
	float maxLength=12000;
	float maxLengthX=(x2-x1)*1.5f;
	float maxLengthY=(y2-y1)*1.5f;
	xmid=1-(sqrt(fabs(x2))/(sqrt(fabs(x2))+sqrt(fabs(x1))));
	ymid=1-(sqrt(fabs(y2))/(sqrt(fabs(y2))+sqrt(fabs(y1))));
	//logOutput.Print("%.0f %.0f %.2f %.0f",y1,y2,ymid,maxLengthY);

	shadowMatrix[0]=cross1.x/maxLengthX;
	shadowMatrix[4]=cross1.y/maxLengthX;
	shadowMatrix[8]=cross1.z/maxLengthX;
	shadowMatrix[12]=-(cross1.dot(centerPos))/maxLengthX;
	shadowMatrix[1]=cross2.x/maxLengthY;
	shadowMatrix[5]=cross2.y/maxLengthY;
	shadowMatrix[9]=cross2.z/maxLengthY;
	shadowMatrix[13]=-(cross2.dot(centerPos))/maxLengthY;
	shadowMatrix[2]=-sundir.x/maxLength;
	shadowMatrix[6]=-sundir.y/maxLength;
	shadowMatrix[10]=-sundir.z/maxLength;
	shadowMatrix[14]=(centerPos.x*sundir.x+centerPos.z*sundir.z)/maxLength+0.5f;
	glLoadMatrixf(shadowMatrix.m);
	glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,16, xmid,ymid,0,0);	//these registers should not be overwritten by anything

	GetShadowMapSizeFactors(p17, p18);

	glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,17, p17,p17,0.0f,0.0f);	//these registers should not be overwritten by anything
	glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB,18, p18,p18,0.0f,0.0f);	//these registers should not be overwritten by anything

	float3 oldup=camera->up;
	camera->right=shadowHandler->cross1;
	camera->up=shadowHandler->cross2;
	camera->pos2=camera->pos+sundir*8000;

	DrawShadowPasses();

	camera->up=oldup;
	camera->pos2=camera->pos;

	shadowMatrix[14]-=0.00001f;

	glShadeModel(GL_SMOOTH);
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

	fb.Unbind();
	glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
}
Beispiel #2
0
void CShadowHandler::CreateShadows(void)
{
	fb.Bind();

	glDisable(GL_BLEND);
	glDisable(GL_LIGHTING);
	glDisable(GL_ALPHA_TEST);
	glDisable(GL_TEXTURE_2D);

	glShadeModel(GL_FLAT);
	glColor4f(1, 1, 1, 1);
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
	glDepthMask(GL_TRUE);
	glEnable(GL_DEPTH_TEST);

	glViewport(0, 0, shadowMapSize, shadowMapSize);

	// glClearColor(0, 0, 0, 0);
	// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClear(GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, 1, 0, 1, 0, -1);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();


	cross1 = (mapInfo->light.sunDir.cross(UpVector)).ANormalize();
	cross2 = cross1.cross(mapInfo->light.sunDir);
	centerPos = camera->pos;

	//! derive the size of the shadow-map from the
	//! intersection points of the camera frustum
	//! with the xz-plane
	CalcMinMaxView();
	SetShadowMapSizeFactors();

	// it should be possible to tweak a bit more shadow map resolution from this
	const float maxLength = 12000.0f;
	const float maxLengthX = (x2 - x1) * 1.5f;
	const float maxLengthY = (y2 - y1) * 1.5f;

	#if (SHADOWMATRIX_NONLINEAR == 1)
	xmid = 1.0f - (sqrt(fabs(x2)) / (sqrt(fabs(x2)) + sqrt(fabs(x1))));
	ymid = 1.0f - (sqrt(fabs(y2)) / (sqrt(fabs(y2)) + sqrt(fabs(y1))));
	#else
	xmid = 0.5f;
	ymid = 0.5f;
	#endif

	shadowMatrix[ 0] =   cross1.x / maxLengthX;
	shadowMatrix[ 4] =   cross1.y / maxLengthX;
	shadowMatrix[ 8] =   cross1.z / maxLengthX;
	shadowMatrix[12] = -(cross1.dot(centerPos)) / maxLengthX;
	shadowMatrix[ 1] =   cross2.x / maxLengthY;
	shadowMatrix[ 5] =   cross2.y / maxLengthY;
	shadowMatrix[ 9] =   cross2.z / maxLengthY;
	shadowMatrix[13] = -(cross2.dot(centerPos)) / maxLengthY;
	shadowMatrix[ 2] = -mapInfo->light.sunDir.x / maxLength;
	shadowMatrix[ 6] = -mapInfo->light.sunDir.y / maxLength;
	shadowMatrix[10] = -mapInfo->light.sunDir.z / maxLength;
	shadowMatrix[14] = ((centerPos.x * mapInfo->light.sunDir.x + centerPos.z * mapInfo->light.sunDir.z) / maxLength) + 0.5f;

	glLoadMatrixf(shadowMatrix.m);

	//! set the shadow-parameter registers
	//! NOTE: so long as any part of Spring rendering still uses
	//! ARB programs at run-time, these lines can not be removed
	//! (all ARB programs share the same environment)
	glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 16, xmid, ymid, 0.0f, 0.0f);
	glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 17,  p17,  p17, 0.0f, 0.0f);
	glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 18,  p18,  p18, 0.0f, 0.0f);

	if (globalRendering->haveGLSL) {
		for (int i = 0; i < SHADOWGEN_PROGRAM_LAST; i++) {
			shadowGenProgs[i]->Enable();
			shadowGenProgs[i]->SetUniform4f(0, xmid, ymid, p17, p18);
			shadowGenProgs[i]->Disable();
		}
	}

	//! move view into sun-space
	float3 oldup = camera->up;
	camera->right = cross1;
	camera->up = cross2;
	camera->pos2 = camera->pos + mapInfo->light.sunDir * 8000;

	DrawShadowPasses();

	camera->up = oldup;
	camera->pos2 = camera->pos;

	shadowMatrix[14] -= 0.00001f;

	glShadeModel(GL_SMOOTH);
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

	//we do this later to save render context switches (this is one of the slowest opengl operations!)
	//fb.Unbind();
	//glViewport(globalRendering->viewPosX,0,globalRendering->viewSizeX,globalRendering->viewSizeY);
}