概念の証明の一部として、私はGLSLスクリプトを構築するために使用できるコードを作成しようとしています。私がやった最初のことの1つは、GLSL型への参照を作成し、GLSLでそれを表す文字列リテラル(GLSLデータ型の型)であるenumに基づいてクエリを実行できるシステムを作成することですコード。このコードで重複を取り除くにはどうすればよいですか?
#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
これまでのところ、私はコードの機能で問題はなかったが、私は列挙型として型を定義するコードの重複し、それらを書きました:ここでは次のようになります。もう一度文字列リテラルが間違いなく私に迷惑をかけています。私はより多くの型を追加する必要があります(これらは唯一のGLSL型です!)、OpenCLカーネルコードを書くための同様のコードを書くことにします(これは同様のセマンティクスに依存します)。私は各タイプの1つの宣言が必要なので、コードダウン?
また、私のマクロの使用を減らすか、または排除する助言があれば、喜んでいただけると思います。
私はこれを私のニーズに適応させる必要がありますが、テストしてそれが機能するかどうかを確認します。 – Xirema