Exemplo n.º 1
0
void GraphicsGL2::SetupScene(
	float fov, float new_view_distance,
	const Vec3 cam_position,
	const Quat & cam_rotation,
	const Vec3 & dynamic_reflection_sample_pos)
{
	// setup the default camera from the passed-in parameters
	{
		GraphicsCamera & cam = cameras["default"];
		cam.fov = fov;
		cam.pos = cam_position;
		cam.orient = cam_rotation;
		cam.view_distance = new_view_distance;
		cam.w = w;
		cam.h = h;
	}

	// create a camera for the skybox with a long view distance
	{
		GraphicsCamera & cam = cameras["skybox"];
		cam = cameras["default"];
		cam.view_distance = 10000;
		cam.pos = Vec3(0);
	}

	// create a camera for the dynamic reflections
	{
		GraphicsCamera & cam = cameras["dynamic_reflection"];
		cam.pos = dynamic_reflection_sample_pos;
		cam.fov = 90; // this gets automatically overridden with the correct fov (which is 90 anyway)
		cam.orient.LoadIdentity(); // this gets automatically rotated for each cube side
		cam.view_distance = 100;
		cam.w = 1; // this gets automatically overridden with the cubemap dimensions
		cam.h = 1; // this gets automatically overridden with the cubemap dimensions
	}

	// create a camera for the dynamic reflection skybox
	{
		GraphicsCamera & cam = cameras["dynamic_reflection_skybox"];
		cam = cameras["dynamic_reflection"];
		cam.view_distance = 10000;
		cam.pos = Vec3(0);
	}

	// create an ortho camera for 2d drawing
	{
		GraphicsCamera & cam = cameras["2d"];

		// this is the glOrtho call we want: glOrtho( 0, 1, 1, 0, -1, 1 );
		cam.orthomode = true;
		cam.orthomin = Vec3(0, 1, -1);
		cam.orthomax = Vec3(1, 0, 1);
	}

	// put the default camera transform into texture3, needed by shaders only
	Mat4 viewMatrix;
	cam_rotation.GetMatrix4(viewMatrix);
	float translate[4] = {-cam_position[0], -cam_position[1], -cam_position[2], 0};
	viewMatrix.MultiplyVector4(translate);
	viewMatrix.Translate(translate[0], translate[1], translate[2]);

	glMatrixMode(GL_TEXTURE);

	glActiveTexture(GL_TEXTURE3);
	glLoadMatrixf(viewMatrix.GetArray());

	// create cameras for shadow passes
	if (shadows)
	{
		Mat4 viewMatrixInv = viewMatrix.Inverse();

		// derive light rotation quaternion from light direction vector
		Quat light_rotation;
		Vec3 up(0, 0, 1);
		float cosa = up.dot(light_direction);
		if (cosa * cosa < 1.0f)
		{
			float a = -acosf(cosa);
			Vec3 x = up.cross(light_direction).Normalize();
			light_rotation.SetAxisAngle(a, x[0], x[1], x[2]);
		}

		std::vector <std::string> shadow_names;
		shadow_names.push_back("near");
		shadow_names.push_back("medium");
		shadow_names.push_back("far");

		for (int i = 0; i < 3; i++)
		{
			float shadow_radius = (1<<i)*closeshadow+(i)*20.0; //5,30,60

			Vec3 shadowbox(1,1,1);
			shadowbox = shadowbox * (shadow_radius*sqrt(2.0));
			Vec3 shadowoffset(0,0,-1);
			shadowoffset = shadowoffset * shadow_radius;
			(-cam_rotation).RotateVector(shadowoffset);
			shadowbox[2] += 60.0;

			GraphicsCamera & cam = cameras["shadows_"+shadow_names[i]];
			cam = cameras["default"];
			cam.orthomode = true;
			cam.orthomin = -shadowbox;
			cam.orthomax = shadowbox;
			cam.pos = cam.pos + shadowoffset;
			cam.orient = light_rotation;

			// go through and extract the clip matrix, storing it in a texture matrix
			// premultiply the clip matrix with default camera view inverse matrix
			renderscene.SetOrtho(cam.orthomin, cam.orthomax);
			renderscene.SetCameraInfo(cam.pos, cam.orient, cam.fov, cam.view_distance, cam.w, cam.h);

			Mat4 clipmat;
			clipmat.Scale(0.5f);
			clipmat.Translate(0.5f, 0.5f, 0.5f);
			clipmat = renderscene.GetProjMatrix().Multiply(clipmat);
			clipmat = renderscene.GetViewMatrix().Multiply(clipmat);
			clipmat = viewMatrixInv.Multiply(clipmat);

			glActiveTexture(GL_TEXTURE4+i);
			glLoadMatrixf(clipmat.GetArray());
		}
	}

	glActiveTexture(GL_TEXTURE0);
	glMatrixMode(GL_MODELVIEW);
}
Exemplo n.º 2
0
void GRAPHICS_GL2::SetupScene(
	float fov, float new_view_distance,
	const MATHVECTOR <float, 3> cam_position,
	const QUATERNION <float> & cam_rotation,
	const MATHVECTOR <float, 3> & dynamic_reflection_sample_pos)
{
	// setup the default camera from the passed-in parameters
	{
		GRAPHICS_CAMERA & cam = cameras["default"];
		cam.fov = fov;
		cam.pos = cam_position;
		cam.orient = cam_rotation;
		cam.view_distance = new_view_distance;
		cam.w = w;
		cam.h = h;
	}

	// create a camera for the skybox with a long view distance
	{
		GRAPHICS_CAMERA & cam = cameras["skybox"];
		cam = cameras["default"];
		cam.view_distance = 10000.0;
	}

	// create a camera for 3d ui elements that has a fixed FOV
	{
		GRAPHICS_CAMERA & cam = cameras["ui3d"];
		cam.fov = 45;
		cam.pos = cam_position;
		cam.orient = cam_rotation;
		cam.view_distance = new_view_distance;
		cam.w = w;
		cam.h = h;
	}

	// create a camera for the dynamic reflections
	{
		GRAPHICS_CAMERA & cam = cameras["dynamic_reflection"];
		cam.pos = dynamic_reflection_sample_pos;
		cam.fov = 90; // this gets automatically overridden with the correct fov (which is 90 anyway)
		cam.orient.LoadIdentity(); // this gets automatically rotated for each cube side
		cam.view_distance = 100.f;
		cam.w = 1.f; // this gets automatically overridden with the cubemap dimensions
		cam.h = 1.f; // this gets automatically overridden with the cubemap dimensions
	}

	// create a camera for the dynamic reflection skybox
	{
		GRAPHICS_CAMERA & cam = cameras["dynamic_reflection_skybox"];
		cam = cameras["dynamic_reflection"];
		cam.view_distance = 10000.f;
	}

	// create an ortho camera for 2d drawing
	{
		GRAPHICS_CAMERA & cam = cameras["2d"];

		// this is the glOrtho call we want: glOrtho( 0, 1, 1, 0, -1, 1 );
		cam.orthomode = true;
		cam.orthomin = MATHVECTOR <float, 3> (0, 1, -1);
		cam.orthomax = MATHVECTOR <float, 3> (1, 0, 1);
	}

	// put the default camera transform into texture3, needed by shaders only
	MATRIX4<float> viewMatrix;
	cam_rotation.GetMatrix4(viewMatrix);
	float translate[4] = {-cam_position[0], -cam_position[1], -cam_position[2], 0};
	viewMatrix.MultiplyVector4(translate);
	viewMatrix.Translate(translate[0], translate[1], translate[2]);

	glActiveTexture(GL_TEXTURE3);
	glMatrixMode(GL_TEXTURE);
	glLoadMatrixf(viewMatrix.GetArray());

	// create cameras for shadow passes
	if (shadows)
	{
		MATRIX4<float> viewMatrixInv = viewMatrix.Inverse();

		std::vector <std::string> shadow_names;
		shadow_names.push_back("near");
		shadow_names.push_back("medium");
		shadow_names.push_back("far");

		for (int i = 0; i < 3; i++)
		{
			float shadow_radius = (1<<i)*closeshadow+(i)*20.0; //5,30,60

			MATHVECTOR <float, 3> shadowbox(1,1,1);
			shadowbox = shadowbox * (shadow_radius*sqrt(2.0));
			MATHVECTOR <float, 3> shadowoffset(0,0,-1);
			shadowoffset = shadowoffset * shadow_radius;
			(-cam_rotation).RotateVector(shadowoffset);
			shadowbox[2] += 60.0;

			GRAPHICS_CAMERA & cam = cameras["shadows_"+shadow_names[i]];
			cam = cameras["default"];
			cam.orthomode = true;
			cam.orthomin = -shadowbox;
			cam.orthomax = shadowbox;
			cam.pos = cam.pos + shadowoffset;
			cam.orient = lightdirection;

			// go through and extract the clip matrix, storing it in a texture matrix
			// premultiply the clip matrix with default camera view inverse matrix
			renderscene.SetOrtho(cam.orthomin, cam.orthomax);
			renderscene.SetCameraInfo(cam.pos, cam.orient, cam.fov, cam.view_distance, cam.w, cam.h);

			MATRIX4<float> clipmat;
			clipmat.Scale(0.5f);
			clipmat.Translate(0.5f, 0.5f, 0.5f);
			clipmat = renderscene.GetProjMatrix().Multiply(clipmat);
			clipmat = renderscene.GetViewMatrix().Multiply(clipmat);
			clipmat = viewMatrixInv.Multiply(clipmat);

			glActiveTexture(GL_TEXTURE4+i);
			glLoadMatrixf(clipmat.GetArray());
		}
	}

	glMatrixMode(GL_MODELVIEW);
	glActiveTexture(GL_TEXTURE0);
}
Exemplo n.º 3
0
void GraphicsGL3::SetupScene(
    float fov, float new_view_distance,
    const Vec3 cam_position,
    const Quat & cam_rotation,
    const Vec3 & /*dynamic_reflection_sample_pos*/,
    std::ostream & error_output)
{
    lastCameraPosition = cam_position;

    const float nearDistance = 0.1;

    setCameraPerspective("default",
                         cam_position,
                         cam_rotation,
                         fov,
                         nearDistance,
                         new_view_distance,
                         w,
                         h);

    Vec3 skyboxCamPosition(0,0,0);
    if (fixed_skybox)
        skyboxCamPosition[2] = cam_position[2];

    setCameraPerspective("skybox",
                         skyboxCamPosition,
                         cam_rotation,
                         fov,
                         nearDistance,
                         10000.f,
                         w,
                         h);

    // derive light rotation quaternion from light direction vector
    Quat light_rotation;
    Vec3 up(0, 0, 1);
    float cosa = up.dot(light_direction);
    if (cosa * cosa < 1.0f)
    {
        float a = -acosf(cosa);
        Vec3 x = up.cross(light_direction).Normalize();
        light_rotation.SetAxisAngle(a, x[0], x[1], x[2]);
    }

    // shadow cameras
    for (int i = 0; i < 3; i++)
    {
        //float shadow_radius = (1<<i)*closeshadow+(i)*20.0; //5,30,60
        float shadow_radius = (1<<(2-i))*closeshadow+(2-i)*20.0;

        Vec3 shadowbox(1,1,1);
        //shadowbox = shadowbox * (shadow_radius*sqrt(2.0));
        shadowbox = shadowbox * (shadow_radius*1.5);
        Vec3 shadowoffset(0,0,-1);
        shadowoffset = shadowoffset * shadow_radius;
        (-cam_rotation).RotateVector(shadowoffset);
        if (i == 2)
            shadowbox[2] += 25.0;
        Vec3 shadowPosition = cam_position+shadowoffset;

        // snap the shadow camera's location to shadow map texels
        // this can be commented out to minimize car aliasing at the expense of scenery aliasing
        const float shadowMapResolution = 512;
        float snapToGridSize = 2.f*shadowbox[0]/shadowMapResolution;
        Vec3 cameraSpaceShadowPosition = shadowPosition;
        light_rotation.RotateVector(cameraSpaceShadowPosition);
        for (int n = 0; n < 3; n++)
        {
            float pos = cameraSpaceShadowPosition[n];
            float gridpos = pos / snapToGridSize;
            gridpos = floor(gridpos);
            cameraSpaceShadowPosition[n] = gridpos*snapToGridSize;
        }
        (-light_rotation).RotateVector(cameraSpaceShadowPosition);
        shadowPosition = cameraSpaceShadowPosition;

        std::string suffix = Utils::tostr(i+1);

        CameraMatrices & shadowcam = setCameraOrthographic("shadow"+suffix,
                                     shadowPosition,
                                     light_rotation,
                                     -shadowbox,
                                     shadowbox);

        std::string matrixName = "shadowMatrix";

        // create and send shadow reconstruction matrices
        // the reconstruction matrix should transform from view to world, then from world to shadow view, then from shadow view to shadow clip space
        const CameraMatrices & defaultcam = cameras.find("default")->second;
        Mat4 shadowReconstruction = defaultcam.inverseViewMatrix.Multiply(shadowcam.viewMatrix).Multiply(shadowcam.projectionMatrix);
        /*//Mat4 shadowReconstruction = shadowcam.projectionMatrix.Multiply(shadowcam.viewMatrix.Multiply(defaultcam.inverseViewMatrix));
        std::cout << "shadowcam.projectionMatrix: " << std::endl;
        shadowcam.projectionMatrix.DebugPrint(std::cout);
        std::cout << "defaultcam.inverseViewMatrix: " << std::endl;
        defaultcam.inverseViewMatrix.DebugPrint(std::cout);
        std::cout << "shadowcam.viewMatrix: " << std::endl;
        shadowcam.viewMatrix.DebugPrint(std::cout);
        std::cout << "defaultcam.inverseViewMatrix.Multiply(shadowcam.viewMatrix): " << std::endl;
        defaultcam.inverseViewMatrix.Multiply(shadowcam.viewMatrix).DebugPrint(std::cout);
        std::cout << matrixName << ":" << std::endl;
        shadowReconstruction.DebugPrint(std::cout);*/

        //renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId(matrixName), shadowReconstruction.GetArray(),16));

        // examine the user-defined fields to find out which shadow matrix to send to a pass
        std::vector <StringId> passes = renderer.getPassNames();
        for (std::vector <StringId>::const_iterator i = passes.begin(); i != passes.end(); i++)
        {
            std::map <std::string, std::string> fields = renderer.getUserDefinedFields(*i);
            std::map <std::string, std::string>::const_iterator field = fields.find(matrixName);
            if (field != fields.end() && field->second == suffix)
            {
                renderer.setPassUniform(*i, RenderUniformEntry(stringMap.addStringId(matrixName), shadowReconstruction.GetArray(),16));
            }
        }
    }

    // send cameras to passes
    for (std::map <std::string, std::string>::const_iterator i = passNameToCameraName.begin(); i != passNameToCameraName.end(); i++)
    {
        renderer.setPassUniform(stringMap.addStringId(i->first), RenderUniformEntry(stringMap.addStringId("viewMatrix"), cameras[i->second].viewMatrix.GetArray(),16));
        renderer.setPassUniform(stringMap.addStringId(i->first), RenderUniformEntry(stringMap.addStringId("projectionMatrix"), cameras[i->second].projectionMatrix.GetArray(),16));
    }

    // send matrices for the default camera
    const CameraMatrices & defaultCamera = cameras.find("default")->second;
    renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("invProjectionMatrix"), defaultCamera.inverseProjectionMatrix.GetArray(),16));
    renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("invViewMatrix"), defaultCamera.inverseViewMatrix.GetArray(),16));
    renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("defaultViewMatrix"), defaultCamera.viewMatrix.GetArray(),16));
    renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("defaultProjectionMatrix"), defaultCamera.projectionMatrix.GetArray(),16));

    // send sun light direction for the default camera

    // transform to eyespace (view space)
    MathVector <float, 4> lightDirection4;
    for (int i = 0; i < 3; i++)
        lightDirection4[i] = light_direction[i];
    lightDirection4[3] = 0;
    defaultCamera.viewMatrix.MultiplyVector4(&lightDirection4[0]);

    // upload to the shaders
    RenderUniformEntry lightDirectionUniform(stringMap.addStringId("eyespaceLightDirection"), &lightDirection4[0], 3);
    renderer.setGlobalUniform(lightDirectionUniform);

    // set the reflection strength
    // TODO: read this from the track definition
    float reflectedLightColor[4];
    for (int i = 0; i < 3; i++)
        reflectedLightColor[i] = 0.5;
    reflectedLightColor[3] = 1.;
    renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("reflectedLightColor"), reflectedLightColor, 4));

    // set the ambient strength
    // TODO: read this from the track definition
    float ambientLightColor[4];
    for (int i = 0; i < 3; i++)
        ambientLightColor[i] = 1.56;
    ambientLightColor[3] = 1.;
    renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("ambientLightColor"), ambientLightColor, 4));

    // set the sun strength
    // TODO: read this from the track definition
    float directionalLightColor[4];
    for (int i = 0; i < 3; i++)
        directionalLightColor[i] = 8.3;
    directionalLightColor[3] = 1.;
    renderer.setGlobalUniform(RenderUniformEntry(stringMap.addStringId("directionalLightColor"), directionalLightColor, 4));

    AssembleDrawMap(error_output);
}
Exemplo n.º 4
0
void GraphicsGL2::SetupScene(
	float fov, float new_view_distance,
	const Vec3 cam_position,
	const Quat & cam_rotation,
	const Vec3 & dynamic_reflection_sample_pos,
	std::ostream & error_output)
{
	// setup the default camera from the passed-in parameters
	{
		GraphicsCamera & cam = cameras["default"];
		cam.fov = fov;
		cam.pos = cam_position;
		cam.rot = cam_rotation;
		cam.view_distance = new_view_distance;
		cam.w = w;
		cam.h = h;
	}

	// create a camera for the skybox with a long view distance
	{
		GraphicsCamera & cam = cameras["skybox"];
		cam = cameras["default"];
		cam.view_distance = 10000;
		cam.pos = Vec3(0);
		if (fixed_skybox)
			cam.pos[2] = cam_position[2];
	}

	// create a camera for the dynamic reflections
	{
		GraphicsCamera & cam = cameras["dynamic_reflection"];
		cam.pos = dynamic_reflection_sample_pos;
		cam.fov = 90; // this gets automatically overridden with the correct fov (which is 90 anyway)
		cam.rot.LoadIdentity(); // this gets automatically rotated for each cube side
		cam.view_distance = 100;
		cam.w = 1; // this gets automatically overridden with the cubemap dimensions
		cam.h = 1; // this gets automatically overridden with the cubemap dimensions
	}

	// create a camera for the dynamic reflection skybox
	{
		GraphicsCamera & cam = cameras["dynamic_reflection_skybox"];
		cam = cameras["dynamic_reflection"];
		cam.view_distance = 10000;
		cam.pos = Vec3(0);
	}

	// create an ortho camera for 2d drawing
	{
		GraphicsCamera & cam = cameras["2d"];

		// this is the glOrtho call we want: glOrtho( 0, 1, 1, 0, -1, 1 );
		cam.orthomode = true;
		cam.orthomin = Vec3(0, 1, -1);
		cam.orthomax = Vec3(1, 0, 1);
	}

	// create cameras for shadow passes
	if (shadows)
	{
		Mat4 view_matrix;
		cam_rotation.GetMatrix4(view_matrix);
		float translate[4] = {-cam_position[0], -cam_position[1], -cam_position[2], 0};
		view_matrix.MultiplyVector4(translate);
		view_matrix.Translate(translate[0], translate[1], translate[2]);

		Mat4 view_matrix_inv = view_matrix.Inverse();

		// derive light rotation quaternion from light direction vector
		Quat light_rotation;
		Vec3 up(0, 0, 1);
		float cosa = up.dot(light_direction);
		if (cosa * cosa < 1.0f)
		{
			float a = -acosf(cosa);
			Vec3 x = up.cross(light_direction).Normalize();
			light_rotation.SetAxisAngle(a, x[0], x[1], x[2]);
		}

		std::vector <std::string> shadow_names;
		shadow_names.push_back("near");
		shadow_names.push_back("medium");
		shadow_names.push_back("far");

		for (int i = 0; i < 3; i++)
		{
			float shadow_radius = (1<<i)*closeshadow+(i)*20.0; //5,30,60

			Vec3 shadowbox(1,1,1);
			shadowbox = shadowbox * (shadow_radius*sqrt(2.0));
			Vec3 shadowoffset(0,0,-1);
			shadowoffset = shadowoffset * shadow_radius;
			(-cam_rotation).RotateVector(shadowoffset);
			shadowbox[2] += 60.0;

			GraphicsCamera & cam = cameras["shadows_"+shadow_names[i]];
			cam = cameras["default"];
			cam.orthomode = true;
			cam.orthomin = -shadowbox;
			cam.orthomax = shadowbox;
			cam.pos = cam.pos + shadowoffset;
			cam.rot = light_rotation;

			// get camera clip matrix
			const Mat4 cam_proj_mat = GetProjMatrix(cam);
			const Mat4 cam_view_mat = GetViewMatrix(cam);

			Mat4 clip_matrix;
			clip_matrix.Scale(0.5f);
			clip_matrix.Translate(0.5f, 0.5f, 0.5f);
			clip_matrix = cam_proj_mat.Multiply(clip_matrix);
			clip_matrix = cam_view_mat.Multiply(clip_matrix);

			// premultiply the clip matrix with default camera view inverse matrix
			clip_matrix = view_matrix_inv.Multiply(clip_matrix);

			shadow_matrix[i] = clip_matrix;
		}

		assert(shadow_distance < 3);
		renderscene.SetShadowMatrix(shadow_matrix, shadow_distance + 1);
		postprocess.SetShadowMatrix(shadow_matrix, shadow_distance + 1);
	}
	else
	{
		renderscene.SetShadowMatrix(NULL, 0);
		postprocess.SetShadowMatrix(NULL, 0);
	}

	// sort the two dimentional drawlist so we get correct ordering
	std::sort(dynamic_drawlist.twodim.begin(), dynamic_drawlist.twodim.end(), &SortDraworder);

	// do fast culling queries for static geometry per pass
	ClearCulledDrawLists();
	for (std::vector <GraphicsConfigPass>::const_iterator i = config.passes.begin(); i != config.passes.end(); i++)
	{
		CullScenePass(*i, error_output);
	}

	renderscene.SetFSAA(fsaa);
	renderscene.SetContrast(contrast);
	renderscene.SetSunDirection(light_direction);

	postprocess.SetContrast(contrast);
	postprocess.SetSunDirection(light_direction);
}