Ejemplo n.º 1
0
void CShadowHandler::CreateShadows()
{
	// NOTE:
	//   we unbind later in WorldDrawer::GenerateIBLTextures() to save render
	//   context switches (which are one of the slowest OpenGL operations!)
	//   together with VP restoration
	fb.Bind();

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

	glShadeModel(GL_FLAT);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
	glDepthMask(GL_TRUE);
	glEnable(GL_DEPTH_TEST);
	glClear(GL_DEPTH_BUFFER_BIT);


	CCamera* prvCam = CCamera::GetSetActiveCamera(CCamera::CAMTYPE_SHADOW);
	CCamera* curCam = CCamera::GetActiveCamera();


	SetShadowMapSizeFactors();
	SetShadowMatrix(prvCam, curCam);
	SetShadowCamera(curCam);

	if (globalRendering->haveARB) {
		// 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, shadowTexProjCenter.x, shadowTexProjCenter.y, 0.0f, 0.0f);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 17, shadowTexProjCenter.z, shadowTexProjCenter.z, 0.0f, 0.0f);
		glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 18, shadowTexProjCenter.w, shadowTexProjCenter.w, 0.0f, 0.0f);
	}

	if (globalRendering->haveGLSL) {
		for (int i = 0; i < SHADOWGEN_PROGRAM_LAST; i++) {
			shadowGenProgs[i]->Enable();
			shadowGenProgs[i]->SetUniform4fv(0, &shadowTexProjCenter.x);
			shadowGenProgs[i]->Disable();
		}
	}

	if ((sky->GetLight())->GetLightIntensity() > 0.0f)
		DrawShadowPasses();


	CCamera::SetActiveCamera(prvCam->GetCamType());
	prvCam->Update();


	glShadeModel(GL_SMOOTH);
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}
Ejemplo n.º 2
0
void CShadowHandler::CreateShadows()
{
	fb.Bind();

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

	glShadeModel(GL_FLAT);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
	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();


	const ISkyLight* L = sky->GetLight();

	// sun direction is in world-space, invert it
	sunDirZ = -L->GetLightDir();
	sunDirX = (sunDirZ.cross(UpVector)).ANormalize();
	sunDirY = (sunDirX.cross(sunDirZ)).ANormalize();

	SetShadowMapSizeFactors();

	// NOTE:
	//     the xy-scaling factors from CalcMinMaxView do not change linearly
	//     or smoothly with camera movements, creating visible artefacts (eg.
	//     large jumps in shadow resolution)
	//
	//     therefore, EITHER use "fixed" scaling values such that the entire
	//     map barely fits into the sun's frustum (by pretending it is embedded
	//     in a sphere and taking its diameter), OR variable scaling such that
	//     everything that can be seen by the camera maximally fills the sun's
	//     frustum (choice of projection-style is left to the user and can be
	//     changed at run-time)
	//
	//     the first option means larger maps will have more blurred/aliased
	//     shadows if the depth buffer is kept at the same size, but no (map)
	//     geometry is ever omitted
	//
	//     the second option means shadows have higher average resolution, but
	//     become less sharp as the viewing volume increases (through eg.camera
	//     rotations) and geometry can be omitted in some cases
	//
	// NOTE:
	//     when DynamicSun is enabled, the orbit is always circular in the xz
	//     plane, instead of elliptical when the map has an aspect-ratio != 1
	//
	const float xyScale = GetShadowProjectionRadius(camera, centerPos, -sunDirZ);
	const float xScale = xyScale;
	const float yScale = xyScale;
	const float zScale = globalRendering->viewRange;

	shadowMatrix[ 0] = sunDirX.x / xScale;
	shadowMatrix[ 1] = sunDirY.x / yScale;
	shadowMatrix[ 2] = sunDirZ.x / zScale;

	shadowMatrix[ 4] = sunDirX.y / xScale;
	shadowMatrix[ 5] = sunDirY.y / yScale;
	shadowMatrix[ 6] = sunDirZ.y / zScale;

	shadowMatrix[ 8] = sunDirX.z / xScale;
	shadowMatrix[ 9] = sunDirY.z / yScale;
	shadowMatrix[10] = sunDirZ.z / zScale;

	// rotate the target position into sun-space for the translation
	shadowMatrix[12] = (-sunDirX.dot(centerPos) / xScale);
	shadowMatrix[13] = (-sunDirY.dot(centerPos) / yScale);
	shadowMatrix[14] = (-sunDirZ.dot(centerPos) / zScale) + 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, shadowTexProjCenter.x, shadowTexProjCenter.y, 0.0f, 0.0f);
	glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 17, shadowTexProjCenter.z, shadowTexProjCenter.z, 0.0f, 0.0f);
	glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, 18, shadowTexProjCenter.w, shadowTexProjCenter.w, 0.0f, 0.0f);

	if (globalRendering->haveGLSL) {
		for (int i = 0; i < SHADOWGEN_PROGRAM_LAST; i++) {
			shadowGenProgs[i]->Enable();
			shadowGenProgs[i]->SetUniform4fv(0, &shadowTexProjCenter.x);
			shadowGenProgs[i]->Disable();
		}
	}

	if (L->GetLightIntensity() > 0.0f) {
		// move view into sun-space
		const float3 oldup = camera->up;

		camera->right = sunDirX;
		camera->up = sunDirY;

		DrawShadowPasses();

		camera->up = oldup;
	}

	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);
}
Ejemplo n.º 3
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);
}