Files
fs2open.github.com/code/graphics/post_processing.cpp

178 lines
5.1 KiB
C++

#include "post_processing.h"
#include "graphics/grinternal.h"
#include "parse/parselo.h"
#include "ship/ship.h"
namespace graphics {
namespace {
PostEffectUniformType mapUniformNameToType(const SCP_string& uniform_name)
{
if (!stricmp(uniform_name.c_str(), "noise_amount")) {
return PostEffectUniformType::NoiseAmount;
} else if (!stricmp(uniform_name.c_str(), "saturation")) {
return PostEffectUniformType::Saturation;
} else if (!stricmp(uniform_name.c_str(), "brightness")) {
return PostEffectUniformType::Brightness;
} else if (!stricmp(uniform_name.c_str(), "contrast")) {
return PostEffectUniformType::Contrast;
} else if (!stricmp(uniform_name.c_str(), "film_grain")) {
return PostEffectUniformType::FilmGrain;
} else if (!stricmp(uniform_name.c_str(), "tv_stripes")) {
return PostEffectUniformType::TvStripes;
} else if (!stricmp(uniform_name.c_str(), "cutoff")) {
return PostEffectUniformType::Cutoff;
} else if (!stricmp(uniform_name.c_str(), "dither")) {
return PostEffectUniformType::Dither;
} else if (!stricmp(uniform_name.c_str(), "tint")) {
return PostEffectUniformType::Tint;
} else {
error_display(0, "Unknown uniform name '%s'!", uniform_name.c_str());
return PostEffectUniformType::Invalid;
}
}
} // namespace
bool PostProcessingManager::parse_table()
{
bool warned = false;
try {
if (cf_exists_full("post_processing.tbl", CF_TYPE_TABLES))
read_file_text("post_processing.tbl", CF_TYPE_TABLES);
else
read_file_text_from_default(defaults_get_file("post_processing.tbl"));
reset_parse();
if (optional_string("#Effects")) {
while (!required_string_one_of(3, "$Name:", "#Ship Effects", "#End")) {
post_effect_t eff;
required_string("$Name:");
stuff_string(eff.name, F_NAME);
required_string("$Uniform:");
SCP_string tbuf;
stuff_string(tbuf, F_NAME);
eff.uniform_type = mapUniformNameToType(tbuf);
required_string("$Define:");
stuff_string(eff.define_name, F_NAME);
required_string("$AlwaysOn:");
stuff_boolean(&eff.always_on);
required_string("$Default:");
stuff_float(&eff.default_intensity);
eff.intensity = eff.default_intensity;
required_string("$Div:");
stuff_float(&eff.div);
required_string("$Add:");
stuff_float(&eff.add);
if (optional_string("$RGB:")) {
stuff_vec3d(&eff.rgb);
}
// Post_effects index is used for flag checks, so we can't have more than 32
if (m_postEffects.size() < 32) {
m_postEffects.push_back(eff);
} else if (!warned) {
mprintf(("WARNING: post_processing.tbl can only have a max of 32 effects! Ignoring extra...\n"));
warned = true;
}
}
}
// Built-in per-ship effects
ship_effect se1;
strcpy_s(se1.name, "FS1 Ship select");
se1.shader_effect = 0;
se1.disables_rendering = false;
se1.invert_timer = false;
Ship_effects.push_back(se1);
if (optional_string("#Ship Effects")) {
while (!required_string_one_of(3, "$Name:", "#Light Shafts", "#End")) {
ship_effect se;
char tbuf[NAME_LENGTH] = {0};
required_string("$Name:");
stuff_string(tbuf, F_NAME, NAME_LENGTH);
strcpy_s(se.name, tbuf);
required_string("$Shader Effect:");
stuff_int(&se.shader_effect);
required_string("$Disables Rendering:");
stuff_boolean(&se.disables_rendering);
required_string("$Invert timer:");
stuff_boolean(&se.invert_timer);
Ship_effects.push_back(se);
}
}
if (optional_string("#Light Shafts")) {
required_string("$AlwaysOn:");
stuff_boolean(&m_lightshaftParams.on);
required_string("$Density:");
stuff_float(&m_lightshaftParams.density);
required_string("$Falloff:");
stuff_float(&m_lightshaftParams.falloff);
required_string("$Weight:");
stuff_float(&m_lightshaftParams.weight);
required_string("$Intensity:");
stuff_float(&m_lightshaftParams.intensity);
required_string("$Sample Number:");
stuff_int(&m_lightshaftParams.samplenum);
m_lightshaftParams.cpintensity = m_lightshaftParams.weight;
float falloff = m_lightshaftParams.falloff;
for (int i = 1; i < m_lightshaftParams.samplenum; ++i)
{
m_lightshaftParams.cpintensity += m_lightshaftParams.weight * falloff;
falloff *= m_lightshaftParams.falloff; // this replaces pow(falloff, i)
}
m_lightshaftParams.cpintensity *= m_lightshaftParams.intensity;
}
required_string("#End");
return true;
} catch (const parse::ParseException& e) {
mprintf(("Unable to parse 'post_processing.tbl'! Error message = %s.\n", e.what()));
return false;
}
}
void PostProcessingManager::clear()
{
m_postEffects.clear();
m_lightshaftParams = lightshaft_parameters();
}
const SCP_vector<graphics::post_effect_t>& PostProcessingManager::getPostEffects() const { return m_postEffects; }
SCP_vector<graphics::post_effect_t>& PostProcessingManager::getPostEffects() { return m_postEffects; }
const lightshaft_parameters& PostProcessingManager::getLightshaftParams() const { return m_lightshaftParams; }
lightshaft_parameters& PostProcessingManager::getLightshaftParams() { return m_lightshaftParams; }
} // namespace graphics
bool gr_lightshafts_enabled()
{
return graphics::Post_processing_manager->getLightshaftParams().on && !Cmdline_force_lightshaft_off;
}