bool GraphicsGL3::Init(
    const std::string & shader_path,
    unsigned resx,
    unsigned resy,
    unsigned antialiasing,
    bool shadows,
    int /*shadow_distance*/,
    int /*shadow_quality*/,
    int reflection_type,
    const std::string & static_reflectionmap_file,
    const std::string & /*static_ambientmap_file*/,
    int anisotropy,
    int texturesize,
    int /*lighting_quality*/,
    bool bloom,
    bool normalmaps,
    bool /*dynamicsky*/,
    const std::string & render_config,
    std::ostream & info_output,
    std::ostream & error_output)
{
    rendercfg = render_config;
    shaderpath = shader_path;

    // first, see if we support the required gl version by attempting to initialize the GL wrapper
    gl.setInfoOutput(info_output);
    gl.setErrorOutput(error_output);
    if (!gl.initialize())
    {
        error_output << "Initialization of GL3 failed." << std::endl;
        return false;
    }

#ifdef _WIN32
    // workaround for broken vao implementation Intel/Windows
    {
        const std::string vendor = (const char*)glGetString(GL_VENDOR);
        if (vendor == "Intel")
            vertex_buffer.BindElementBufferExplicitly();
    }
#endif

    // set up our graphical configuration option conditions
    bool fsaa = (antialiasing > 1);

    // add the conditions to the set
#define ADDCONDITION(x) if (x) conditions.insert(#x)
    ADDCONDITION(bloom);
    ADDCONDITION(normalmaps);
    ADDCONDITION(fsaa);
    ADDCONDITION(shadows);
#undef ADDCONDITION

    if (reflection_type >= 1)
        conditions.insert("reflections_low");
    if (reflection_type >= 2)
        conditions.insert("reflections_high");

    // load the reflection cubemap
    if (!static_reflectionmap_file.empty())
    {
        TextureInfo t;
        t.cube = true;
        t.verticalcross = true;
        t.mipmap = true;
        t.anisotropy = anisotropy;
        t.maxsize = TextureInfo::Size(texturesize);
        static_reflection.Load(static_reflectionmap_file, t, error_output);
    }

    // this information is needed to initialize the renderer in ReloadShaders
    w = resx;
    h = resy;

    // initialize the renderer
    bool success = ReloadShaders(info_output, error_output);
    initialized = success;
    return success;
}
Exemple #2
0
bool GraphicsGL2::EnableShaders(std::ostream & info_output, std::ostream & error_output)
{
	CheckForOpenGLErrors("EnableShaders: start", error_output);

	// unload shaders
	glUseProgramObjectARB(0);
	shaders.clear();
	CheckForOpenGLErrors("EnableShaders: shader unload", error_output);

	// unload inputs/outputs
	render_outputs.clear();
	texture_outputs.clear();
	texture_inputs.clear();
	CheckForOpenGLErrors("EnableShaders: FBO deinit", error_output);

	// reload configuration
	config = GraphicsConfig();
	std::string rcpath = shaderpath + "/" + renderconfigfile;
	if (!config.Load(rcpath, error_output))
	{
		error_output << "EnableShaders: Error loading render configuration file: " << rcpath << std::endl;
		return false;
	}

	bool ssao = (lighting > 0);
	bool ssao_low = (lighting == 1);
	bool ssao_high = (lighting == 2);
	bool reflection_disabled = (reflection_status == REFLECTION_DISABLED);
	bool reflection_dynamic = (reflection_status == REFLECTION_DYNAMIC);
	bool shadows_near = shadows;
	bool shadows_medium = shadows && shadow_distance > 0;
	bool shadows_far = shadows && shadow_distance > 1;
	bool shadow_quality_low = shadows && (shadow_quality == 0);
	bool shadow_quality_medium = shadows && (shadow_quality == 1);
	bool shadow_quality_high = shadows && (shadow_quality == 2);
	bool shadow_quality_vhigh = shadows && (shadow_quality == 3);
	bool shadow_quality_ultra = shadows && (shadow_quality == 4);

	// for now, map vhigh and ultra to high
	shadow_quality_high = shadow_quality_high || shadow_quality_vhigh || shadow_quality_ultra;
	shadow_quality_vhigh = false;
	shadow_quality_ultra = true;

	conditions.clear();
	if (fsaa > 1) conditions.insert("fsaa");
	#define ADDCONDITION(x) if (x) conditions.insert(#x)
	ADDCONDITION(bloom);
	ADDCONDITION(normalmaps);
	ADDCONDITION(ssao);
	ADDCONDITION(ssao_low);
	ADDCONDITION(ssao_high);
	ADDCONDITION(reflection_disabled);
	ADDCONDITION(reflection_dynamic);
	ADDCONDITION(shadows_near);
	ADDCONDITION(shadows_medium);
	ADDCONDITION(shadows_far);
	ADDCONDITION(shadow_quality_low);
	ADDCONDITION(shadow_quality_medium);
	ADDCONDITION(shadow_quality_high);
	ADDCONDITION(shadow_quality_vhigh);
// 		ADDCONDITION(shadow_quality_ultra);
	ADDCONDITION(sky_dynamic);
	#undef ADDCONDITION

	// add some common textures
	if (reflection_status == REFLECTION_STATIC)
		texture_inputs["reflection_cube"] = static_reflection;
	texture_inputs["ambient_cube"] = static_ambient;

	// setup frame buffer textures
	const bool has_texture_float = GLEW_ARB_texture_float && GLEW_ARB_half_float_pixel;
	for (std::vector <GraphicsConfigOutput>::const_iterator i = config.outputs.begin(); i != config.outputs.end(); i++)
	{
		if (!i->conditions.Satisfied(conditions))
			continue;

		if (texture_outputs.find(i->name) != texture_outputs.end())
		{
			error_output << "Ignore duplicate definiion of output: " << i->name << std::endl;
			continue;
		}

		if (i->type == "framebuffer")
		{
			render_outputs[i->name].RenderToFramebuffer(w, h);
		}
		else
		{
			FrameBufferTexture::Target target = TextureTargetFromString(i->type);
			FrameBufferTexture::Format format = TextureFormatFromString(i->format);
			if (!has_texture_float && (format == FrameBufferTexture::RGBA16 || format == FrameBufferTexture::RGB16))
			{
				error_output << "Your video card doesn't support floating point textures." << std::endl;
				error_output << "Failed to load render output: " << i->name << " " << i->type << std::endl;
				return false;
			}

			// initialize fbtexture
			int multisampling = (i->multisample < 0) ? fsaa : 0;
			FrameBufferTexture & fbtex = texture_outputs[i->name];
			fbtex.Init(
				i->width.GetSize(w), i->height.GetSize(h),
				target, format, (i->filter == "nearest"), i->mipmap,
				error_output, multisampling, (i->format == "depthshadow"));

			// register texture as input
			texture_inputs[i->name] = fbtex;
		}

		info_output << "Initialized render output: " << i->name;
		info_output << (i->type != "framebuffer" ? " (FBO)" : " (framebuffer alias)") << std::endl;
	}
	render_outputs["framebuffer"].RenderToFramebuffer(w, h);

	// gen graphics config shaders map
	typedef std::map <std::string, const GraphicsConfigShader *> ConfigShaderMap;
	ConfigShaderMap config_shaders;
	for (std::vector <GraphicsConfigShader>::const_iterator s = config.shaders.begin(); s != config.shaders.end(); s++)
	{
		std::pair <ConfigShaderMap::iterator, bool> result = config_shaders.insert(std::make_pair(s->name, &*s));
		if (!result.second)
			error_output << "Ignore duplicate definition of shader: " << s->name << std::endl;
	}

	// setup frame buffer objects and shaders
	std::vector <std::string> shader_uniforms(Uniforms::str, end(Uniforms::str));
	std::vector <std::string> shader_defines;
	GetShaderDefines(shader_defines);
	for (std::vector <GraphicsConfigPass>::const_iterator i = config.passes.begin(); i != config.passes.end(); i++)
	{
		// check conditions
		if (!i->conditions.Satisfied(conditions))
			continue;

		// load pass output
		const std::string & outname = i->output;
		if (render_outputs.find(outname) == render_outputs.end())
		{
			// collect a list of textures for the outputs
			std::vector <std::string> outputs = Tokenize(outname, " ");
			std::vector <FrameBufferTexture*> fbotex;
			for (std::vector <std::string>::const_iterator o = outputs.begin(); o != outputs.end(); o++)
			{
				texture_output_map_type::iterator to = texture_outputs.find(*o);
				if (to != texture_outputs.end())
				{
					fbotex.push_back(&to->second);
				}
			}
			if (fbotex.empty())
			{
				error_output << "None of these outputs are active: " << outname << std::endl;
				return false;
			}

			// initialize fbo
			FrameBufferObject & fbo = render_outputs[outname].RenderToFBO();
			fbo.Init(glstate, fbotex, error_output);
		}

		// load pass shader
		const std::string & shadername = i->shader;
		if (shaders.find(shadername) == shaders.end())
		{
			ConfigShaderMap::const_iterator csi = config_shaders.find(shadername);
			if (csi == config_shaders.end())
			{
				error_output << "Shader not defined: " << shadername << std::endl;
				return false;
			}
			const GraphicsConfigShader * cs = csi->second;

			std::vector <std::string> defines = Tokenize(cs->defines, " ");
			defines.reserve(defines.size() + shader_defines.size());
			defines.insert(defines.end(), shader_defines.begin(), shader_defines.end());

			Shader & shader = shaders[cs->name];
			if (!shader.Load(
				shaderpath + "/" + cs->vertex,
				shaderpath + "/" + cs->fragment,
				defines, shader_uniforms,
				info_output, error_output))
			{
				return false;
			}
		}
	}

	return true;
}