add '#param' default value syntax

This commit is contained in:
MihailRis 2025-04-04 13:19:25 +03:00
parent 6043ae8331
commit 70cf308771
4 changed files with 74 additions and 6 deletions

View File

@ -8,11 +8,14 @@
#include "io/engine_paths.hpp"
#include "typedefs.hpp"
#include "util/stringutil.hpp"
#include "coders/json.hpp"
#include "data/dv_util.hpp"
#include "coders/BasicParser.hpp"
static debug::Logger logger("glsl-extension");
using Type = PostEffect::Param::Type;
using Value = PostEffect::Param::Value;
void GLSLExtension::setPaths(const ResPaths* paths) {
this->paths = paths;
@ -92,10 +95,10 @@ inline void source_line(std::stringstream& ss, uint linenum) {
ss << "#line " << linenum << "\n";
}
static std::optional<PostEffect::Param::Type> param_type_from(
static std::optional<Type> param_type_from(
const std::string& name
) {
static const std::unordered_map<std::string, PostEffect::Param::Type> typeNames {
static const std::unordered_map<std::string, Type> typeNames {
{"float", Type::FLOAT},
{"vec2", Type::VEC2},
{"vec3", Type::VEC3},
@ -108,6 +111,21 @@ static std::optional<PostEffect::Param::Type> param_type_from(
return found->second;
}
static Value default_value_for(Type type) {
switch (type) {
case Type::FLOAT:
return 0.0f;
case Type::VEC2:
return glm::vec2 {0.0f, 0.0f};
case Type::VEC3:
return glm::vec3 {0.0f, 0.0f, 0.0f};
case Type::VEC4:
return glm::vec4 {0.0f, 0.0f, 0.0f, 0.0f};
default:
throw std::runtime_error("unsupported type");
}
}
class GLSLParser : public BasicParser<char> {
public:
GLSLParser(GLSLExtension& glsl, std::string_view file, std::string_view source, bool header)
@ -155,22 +173,68 @@ public:
return false;
}
template<int n>
Value parseVectorValue() {
if (peekNoJump() != '[') {
throw error("'[' expected");
}
// may be more efficient but ok
auto value = json::parse(
filename,
std::string_view(source.data() + pos, source.size() - pos)
);
glm::vec<n, float> vec {};
try {
dv::get_vec<n>(value, vec);
return vec;
} catch (const std::exception& err) {
throw error(err.what());
}
}
Value parseDefaultValue(Type type, const std::string& name) {
switch (type) {
case Type::FLOAT:
return static_cast<float>(parseNumber(1).asNumber());
case Type::VEC2:
return parseVectorValue<2>();
case Type::VEC3:
return parseVectorValue<3>();
case Type::VEC4:
return parseVectorValue<4>();
default:
throw error("unsupported default value for type " + name);
}
}
bool processParamDirective() {
skipWhitespace(false);
// Parse type name
auto typeName = parseName();
auto type = param_type_from(typeName);
if (!type.has_value()) {
throw error("unsupported param type " + util::quote(typeName));
}
skipWhitespace(false);
// Parse parameter name
auto paramName = parseName();
if (params.find(paramName) != params.end()) {
throw error("duplicating param " + util::quote(paramName));
}
skipWhitespace(false);
ss << "uniform " << typeName << " " << paramName << ";\n";
auto defValue = default_value_for(type.value());
// Parse default value
if (peekNoJump() == '=') {
skip(1);
skipWhitespace(false);
defValue = parseDefaultValue(type.value(), typeName);
}
skipLine();
ss << "uniform " << typeName << " " << paramName << ";\n";
params[paramName] = PostEffect::Param(type.value());
params[paramName] = PostEffect::Param(type.value(), std::move(defValue));
return false;
}

View File

@ -4,7 +4,9 @@
PostEffect::Param::Param() : type(Type::FLOAT) {}
PostEffect::Param::Param(Type type) : type(type) {}
PostEffect::Param::Param(Type type, Value defValue)
: type(type), defValue(std::move(defValue)) {
}
PostEffect::PostEffect(std::unique_ptr<Shader> shader)
: shader(std::move(shader)) {

View File

@ -15,9 +15,10 @@ public:
using Value = std::variant<float, glm::vec2, glm::vec3, glm::vec4>;
Type type;
Value defValue;
Param();
Param(Type type);
Param(Type type, Value defValue);
};
PostEffect(std::unique_ptr<Shader> shader);

View File

@ -18,6 +18,7 @@ TEST(GLSLExtension, processing) {
"\n"
"#include /* hell\no */ < sum >\n"
"#param float p_intensity\n"
"#param vec3 p_pos = [0, 0, 0]\n"
"\n"
"vec4 effect() {\n"
" vec4 color = texture(u_screen, v_uv);\n"