Als Teil eines Proof of Concept versuche ich Code zu erstellen, mit dem ich GLSL-Skripte erstellen kann. Eines der ersten Dinge, die ich getan habe, ist die Erstellung von Verweisen auf die GLSL-Typen und das Erstellen eines Systems, in dem ich basierend auf einer Enumeration (dem Typ des GLSL-Datentyps) das String-Literal abfragen kann, das es in GLSL darstellt Code. Hier ist, wie es aussieht:Wie kann ich die Duplizierung in diesem Code loswerden?
#define VEC_EXPAND(name) g ## name ## 2, g ## name ## 3, g ## name ## 4
#define MAT_EXPAND(name) VEC_EXPAND(name), VEC_EXPAND(name ## 2x), VEC_EXPAND(name ## 3x), VEC_EXPAND(name ## 4x)
enum class gtype : uint32_t {
gvoid,
gbool, gint, guint, gfloat, gdouble,
VEC_EXPAND(bvec), VEC_EXPAND(ivec), VEC_EXPAND(uvec), VEC_EXPAND(vec), VEC_EXPAND(dvec),
MAT_EXPAND(mat), MAT_EXPAND(dmat),
gsampler2d
};
#undef VEC_EXPAND
#undef MAT_EXPAND
#define GLSL_EXPAND(name) #name
#define VEC_EXPAND(name) GLSL_EXPAND(name ## 2), GLSL_EXPAND(name ## 3), GLSL_EXPAND(name ## 4)
#define MAT_EXPAND(name) VEC_EXPAND(name), VEC_EXPAND(name ## 2x), VEC_EXPAND(name ## 3x), VEC_EXPAND(name ## 4x)
template<class T, class... Tail, class Elem = typename std::decay<T>::type>
constexpr std::array<Elem, 1 + sizeof...(Tail)> make_array(T&& head, Tail&&... values)
{
return { std::forward<T>(head), std::forward<Tail>(values)... };
}
constexpr auto glsl_string_array = make_array(
"void", "bool", "int", "uint", "float", "double",
VEC_EXPAND(bvec), VEC_EXPAND(ivec), VEC_EXPAND(uvec), VEC_EXPAND(vec), VEC_EXPAND(dvec),
MAT_EXPAND(mat), MAT_EXPAND(dmat),
"sampler2d"
);
constexpr const char * to_string_literal(gtype type) {
return glsl_string_array[uint32_t(type)];
}
std::string to_string(gtype type) {
return to_string_literal(type);
}
#undef GLSL_EXPAND
#undef VEC_EXPAND
#undef MAT_EXPAND
Bisher habe ich mit der Funktionalität des Codes keine Probleme hatte, aber das Duplizierung des Codes, wo ich die Typen als Enum definieren und sie dann schreiben wieder als String-Literal beunruhigt mich definitiv. Ich werde auch mehr Typen hinzufügen müssen (das sind kaum die einzigen GLSL-Typen!) Und ich würde gerne ähnlichen Code zum Schreiben von OpenCL-Kernel-Code schreiben (was von ähnlicher Semantik abhängt), wie kann ich das reduzieren? code down, so dass ich nur eine Deklaration für jeden Typ brauche?
Auch jeder Hinweis, der meine Verwendung von Macros reduzieren oder sogar eliminieren würde, wäre willkommen.
Ich werde dies an meine Bedürfnisse anpassen müssen, aber ich werde es testen und sehen, ob es funktioniert. – Xirema