試した環境
- glm 9.9.7
- Microsoft Visual Studio Community 2019 Version 16.4.5
本題
vector.xyzw
のようなドット演算子の後に指定したい要素を順に並べる表現方法を swizzle または Swizzling と呼ぶそうです。
この swizzle 表現は GLSL ではデフォルトでできるようになっていますが、 GLM ではglm/glm.hpp
を include するだけでは利用できません。
GLM の vec 系の変数で swizzle 表現を利用するためには、#include <glm/glm.hpp>
の前に#define GLM_FORCE_SWIZZLE
を記述します。
#include <iostream> #define GLM_FORCE_SWIZZLE #include <glm/glm.hpp> #include <glm/gtx/string_cast.hpp> int main(int argc, char* argv[]) { glm::vec4 v4(1.f, 2.f, 3.f, 4.f); glm::vec3 v3 = v4.xyz; std::cout << glm::to_string(v3) << std::endl; // vec3(1.000000, 2.000000, 3.000000) v3.yz = v4.xw; std::cout << glm::to_string(v3) << std::endl; // vec3(1.000000, 1.000000, 4.000000) }
ただし、glm の文字列化関数glm::to_string
関数に直接の引数にすることは出来ませんでした。
//std::cout << glm::to_string(v4.xyz) << std::endl; // NG std::cout << glm::to_string(glm::vec3(v4.xyz)) << std::endl; // OK
#define GLM_SWIZZLE
は非推奨
ちなみに、#include <glm/glm.hpp>
の前に#define GLM_SWIZZLE
を記述することでも swizzle 表現が利用できるのですが、
GLM_FORCE_SWIZZLE
が推奨されています。
https://github.com/g-truc/glm#deprecation-1
Removed GLM_SWIZZLE, use GLM_FORCE_SWIZZLE instead
おまけ:glm/gtx/vec_swizzle.hpp
を使う方法
GLSL の swizzle 表現とは違うのですが、
glm/gtx/vec_swizzle.hpp
を include することで、glm::xyz()
などが使えるようになります。
こちらはglm::to_string
関数の引数にできますが、左辺値に使用しての値の書き換えはできません。
#include <iostream> #include <glm/glm.hpp> #include <glm/gtx/string_cast.hpp> #include <glm/gtx/vec_swizzle.hpp> int main(int argc, char* argv[]) { glm::vec4 v4(1.f, 2.f, 3.f, 4.f); glm::vec3 v3 = glm::xyz(v4); std::cout << glm::to_string(v3) << std::endl; // vec3(1.000000, 2.000000, 3.000000) glm::yz(v3) = glm::xw(v4); std::cout << glm::to_string(v3) << std::endl; // vec3(1.000000, 2.000000, 3.000000) // vec3(1.000000, 1.000000, 4.000000) ではない! std::cout << glm::to_string(glm::xyz(v4)) << std::endl; // vec3(1.000000, 2.000000, 3.000000) }
参考
https://github.com/g-truc/glm/blob/master/manual.md#section2_14
https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Swizzling