示例#1
0
void GraphicsGL2::CullScenePass(
	const GraphicsConfigPass & pass,
	std::map <std::string, PtrVector <Drawable> > & culled_static_drawlist,
	std::ostream & error_output)
{
	// for each pass, we have which camera and which draw layer to use
	// we want to do culling for each unique camera and draw layer combination
	// use camera/layer as the unique key
	assert(!pass.draw.empty());

	if (pass.draw.back() == "postprocess" || !pass.conditions.Satisfied(conditions))
		return;

	for (std::vector <std::string>::const_iterator d = pass.draw.begin(); d != pass.draw.end(); d++)
	{
		// determine if we're dealing with a cubemap
		render_output_map_type::iterator oi = render_outputs.find(pass.output);
		if (oi == render_outputs.end())
		{
			ReportOnce(&pass, "Render output "+pass.output+" couldn't be found", error_output);
			return;
		}

		const bool cubemap = (oi->second.IsFBO() && oi->second.RenderToFBO().IsCubemap());
		const int cubesides = cubemap ? 6 : 1;
		std::string cameraname = pass.camera;
		for (int cubeside = 0; cubeside < cubesides; cubeside++)
		{
			if (cubemap)
			{
				// build sub-camera

				// build a name for the sub camera
				{
					std::stringstream converter;
					converter << pass.camera << "_cubeside" << cubeside;
					cameraname = converter.str();
				}

				// get the base camera
				camera_map_type::iterator bci = cameras.find(pass.camera);

				if (bci == cameras.end())
				{
					ReportOnce(&pass, "Camera "+pass.camera+" couldn't be found", error_output);
					return;
				}

				// create our sub-camera
				GraphicsCamera & cam = cameras[cameraname];
				cam = bci->second;

				// set the sub-camera's properties
				cam.rot = GetCubeSideOrientation(cubeside, cam.rot, error_output);
				cam.fov = 90;
				assert(oi->second.IsFBO());
				const FrameBufferObject & fbo = oi->second.RenderToFBO();
				cam.w = fbo.GetWidth();
				cam.h = fbo.GetHeight();
			}

			std::string key = BuildKey(cameraname, *d);
			if (pass.cull)
			{
				camera_map_type::iterator ci = cameras.find(cameraname);
				if (ci == cameras.end())
				{
					ReportOnce(&pass, "Camera "+cameraname+" couldn't be found", error_output);
					return;
				}

				GraphicsCamera & cam = ci->second;
				if (culled_static_drawlist.find(key) == culled_static_drawlist.end())
				{
					Frustum frustum;
					frustum.Extract(GetProjMatrix(cam).GetArray(), GetViewMatrix(cam).GetArray());

					reseatable_reference <AabbTreeNodeAdapter <Drawable> > container =
						static_drawlist.GetDrawlist().GetByName(*d);
					if (!container)
					{
						ReportOnce(&pass, "Drawable container "+*d+" couldn't be found", error_output);
						return;
					}

					container->Query(frustum, culled_static_drawlist[key]);
				}
			}
			else
			{
				reseatable_reference <AabbTreeNodeAdapter <Drawable> > container =
					static_drawlist.GetDrawlist().GetByName(*d);
				if (!container)
				{
					ReportOnce(&pass, "Drawable container "+*d+" couldn't be found", error_output);
					return;
				}

				container->Query(Aabb<float>::IntersectAlways(), culled_static_drawlist[key]);
			}
		}
	}
}
示例#2
0
void GraphicsGL3::AssembleDrawMap(std::ostream & /*error_output*/)
{
    //sort the two dimentional drawlist so we get correct ordering
    std::sort(dynamic_drawlist.twodim.begin(),dynamic_drawlist.twodim.end(),&SortDraworder);

    drawMap.clear();

    // for each pass, we have which camera and which draw groups to use
    // we want to do culling for each unique camera and draw group combination
    // use "camera/group" as a unique key string
    // this is cached to avoid extra memory allocations each frame, so we need to clear old data
    for (std::map <std::string, std::vector <RenderModelExt*> >::iterator i = cameraDrawGroupDrawLists.begin(); i != cameraDrawGroupDrawLists.end(); i++)
    {
        i->second.clear();
    }

    // because the cameraDrawGroupDrawLists are cached, this is how we keep track of which combinations
    // we have already generated
    std::set <std::string> cameraDrawGroupCombinationsGenerated;

    // for each pass, do culling of the dynamic and static drawlists and put the results into the cameraDrawGroupDrawLists
    std::vector <StringId> passes = renderer.getPassNames();
    for (std::vector <StringId>::const_iterator i = passes.begin(); i != passes.end(); i++)
    {
        if (renderer.getPassEnabled(*i))
        {
            const std::set <StringId> & passDrawGroups = renderer.getDrawGroups(*i);
            for (std::set <StringId>::const_iterator g = passDrawGroups.begin(); g != passDrawGroups.end(); g++)
            {
                StringId passName = *i;
                StringId drawGroupName = *g;
                std::string drawGroupString = stringMap.getString(drawGroupName);
                std::string cameraDrawGroupKey = getCameraDrawGroupKey(passName, drawGroupName);

                std::vector <RenderModelExt*> & outDrawList = cameraDrawGroupDrawLists[cameraDrawGroupKey];

                // see if we have already generated this combination
                if (cameraDrawGroupCombinationsGenerated.find(cameraDrawGroupKey) == cameraDrawGroupCombinationsGenerated.end())
                {
                    // we need to generate this combination

                    // extract frustum information
                    RenderUniform proj, view;
                    bool doCull = true;
                    /*if (getCameraForPass(passName).empty())
                    {
                    	doCull = false;
                    }
                    else*/
                    {
                        doCull = !(!doCull || !renderer.getPassUniform(passName, stringMap.addStringId("viewMatrix"), view));
                        doCull = !(!doCull || !renderer.getPassUniform(passName, stringMap.addStringId("projectionMatrix"), proj));
                    }
                    Frustum frustum;
                    Frustum * frustumPtr = NULL;
                    if (doCull)
                    {
                        frustum.Extract(&proj.data[0], &view.data[0]);
                        frustumPtr = &frustum;
                    }

                    // assemble dynamic entries
                    reseatable_reference <PtrVector <Drawable> > dynamicDrawablesPtr = dynamic_drawlist.GetByName(drawGroupString);
                    if (dynamicDrawablesPtr)
                    {
                        const std::vector <Drawable*> & dynamicDrawables = *dynamicDrawablesPtr;
                        //AssembleDrawList(dynamicDrawables, outDrawList, frustumPtr, lastCameraPosition);
                        AssembleDrawList(dynamicDrawables, outDrawList, NULL, lastCameraPosition); // TODO: the above line is commented out because frustum culling dynamic drawables doesen't work at the moment; is the object center in the drawable for the car in the correct space??
                    }

                    // assemble static entries
                    reseatable_reference <AabbTreeNodeAdapter <Drawable> > staticDrawablesPtr = static_drawlist.GetByName(drawGroupString);
                    if (staticDrawablesPtr)
                    {
                        const AabbTreeNodeAdapter <Drawable> & staticDrawables = *staticDrawablesPtr;
                        AssembleDrawList(staticDrawables, outDrawList, frustumPtr, lastCameraPosition);
                    }

                    // if it's requesting the full screen rect draw group, feed it our special drawable
                    if (drawGroupString == "full screen rect")
                    {
                        std::vector <Drawable*> rect;
                        rect.push_back(&fullscreenquad);
                        AssembleDrawList(rect, outDrawList, NULL, lastCameraPosition);
                    }
                }

                // use the generated combination in our drawMap
                drawMap[passName][drawGroupName] = &outDrawList;

                cameraDrawGroupCombinationsGenerated.insert(cameraDrawGroupKey);
            }
        }
    }

    /*for (std::map <std::string, std::vector <RenderModelExternal*> >::iterator i = cameraDrawGroupDrawLists.begin(); i != cameraDrawGroupDrawLists.end(); i++)
    {
    	std::cout << i->first << ": " << i->second.size() << std::endl;
    }
    std::cout << "----------" << std::endl;*/
    //if (enableContributionCull) std::cout << "Contribution cull count: " << assembler.contributionCullCount << std::endl;
    //std::cout << "normal_noblend: " << drawGroups[stringMap.addStringId("normal_noblend")].size() << "/" << static_drawlist.GetDrawList().GetByName("normal_noblend")->size() << std::endl;
}
示例#3
0
void GraphicsGL2::CullScenePass(
	const GraphicsConfigPass & pass,
	std::ostream & error_output)
{
	// for each pass, we have which camera and which draw layer to use
	// we want to do culling for each unique camera and draw layer combination
	// use camera/layer as the unique key
	assert(!pass.draw.empty());

	if (pass.draw.back() == "postprocess" || !pass.conditions.Satisfied(conditions))
		return;

	for (std::vector <std::string>::const_iterator d = pass.draw.begin(); d != pass.draw.end(); d++)
	{
		// determine if we're dealing with a cubemap
		RenderOutputMap::iterator oi = render_outputs.find(pass.output);
		if (oi == render_outputs.end())
		{
			ReportOnce(&pass, "Render output "+pass.output+" couldn't be found", error_output);
			return;
		}

		const bool cubemap = (oi->second.IsFBO() && oi->second.RenderToFBO().IsCubemap());
		const int cubesides = cubemap ? 6 : 1;
		std::string cameraname = pass.camera;
		for (int cubeside = 0; cubeside < cubesides; cubeside++)
		{
			if (cubemap)
			{
				// build a name for the sub camera
				{
					std::ostringstream s;
					s << pass.camera << "_cubeside" << cubeside;
					cameraname = s.str();
				}

				// get the base camera
				CameraMap::iterator bci = cameras.find(pass.camera);
				if (bci == cameras.end())
				{
					ReportOnce(&pass, "Camera " + pass.camera + " couldn't be found", error_output);
					return;
				}

				// create our sub-camera
				GraphicsCamera & cam = cameras[cameraname];
				cam = bci->second;

				// set the sub-camera's properties
				cam.rot = GetCubeSideOrientation(cubeside, cam.rot, error_output);
				cam.fov = 90;
				assert(oi->second.IsFBO());
				const FrameBufferObject & fbo = oi->second.RenderToFBO();
				cam.w = fbo.GetWidth();
				cam.h = fbo.GetHeight();
			}

			const std::string drawlist_name = BuildKey(cameraname, *d);
			CulledDrawList & drawlist = culled_drawlists[drawlist_name];
			if (drawlist.valid)
				break;

			drawlist.valid = true;
			if (pass.cull)
			{
				// cull static drawlist
				reseatable_reference <AabbTreeNodeAdapter <Drawable> > container = static_drawlist.GetByName(*d);
				if (!container)
				{
					ReportOnce(&pass, "Drawable container " + *d + " couldn't be found", error_output);
					return;
				}

				CameraMap::iterator ci = cameras.find(cameraname);
				if (ci == cameras.end())
				{
					ReportOnce(&pass, "Camera " + cameraname + " couldn't be found", error_output);
					return;
				}
				const GraphicsCamera & cam = ci->second;

				Frustum frustum;
				frustum.Extract(GetProjMatrix(cam).GetArray(), GetViewMatrix(cam).GetArray());

				container->Query(frustum, drawlist.drawables);

				// cull dynamic drawlist
				reseatable_reference <PtrVector <Drawable> > container_dynamic = dynamic_drawlist.GetByName(*d);
				if (!container_dynamic)
				{
					ReportOnce(&pass, "Drawable container " + *d + " couldn't be found", error_output);
					return;
				}
				for (size_t i = 0; i < container_dynamic->size(); ++i)
				{
					if (!Cull(frustum, *(*container_dynamic)[i]))
						drawlist.drawables.push_back((*container_dynamic)[i]);
				}
			}
			else
			{
				// copy static drawlist
				reseatable_reference <AabbTreeNodeAdapter <Drawable> > container = static_drawlist.GetByName(*d);
				if (!container)
				{
					ReportOnce(&pass, "Drawable container " + *d + " couldn't be found", error_output);
					return;
				}
				container->Query(Aabb<float>::IntersectAlways(), drawlist.drawables);

				// copy dynamic drawlist
				reseatable_reference <PtrVector <Drawable> > container_dynamic = dynamic_drawlist.GetByName(*d);
				if (!container_dynamic)
				{
					ReportOnce(&pass, "Drawable container " + *d + " couldn't be found", error_output);
					return;
				}
				drawlist.drawables.insert(
					drawlist.drawables.end(),
					container_dynamic->begin(),
					container_dynamic->end());
			}
		}
	}
}