Instantly share code, notes, and snippets.

usagi/file0.txt Last active Aug 29, 2015

What would you like to do?
glm - グラフィックスプログラミングのためのC++数学系ライブラリー ref: http://qiita.com/usagi/items/f34976a3d3011506ff7d
 mkdir -p ~/repos/hello_glm cd ~/repos/hello_glm git init git submodule add git@github.com:g-truc/glm.git submodule/glm
 vim main.cxx
 glm::u16vec3 a( 1, 2, 3 );
 #include #include auto main() -> int { auto p = glm::vec4( 2, 3, 4, 5 ); auto q = glm::vec4( 3, 4, 5, 6 ); // 四則演算の演算子が定義済みで便利に使えます。 // operator+ の例: auto n = p + q; // operator* は単なる次元毎のスカラー積です: auto m = p * q; std::cout << "n ( operator+ ): " << n.x << " " << n.y << " " << n.z << " " << n.w << "\n" << "m ( operator* ): " << m.x << " " << m.y << " " << m.z << " " << m.w << "\n" ; }
 n ( operator+ ): 5 7 9 11 m ( operator* ): 6 12 20 30
 #include #include // あとで gtx 拡張の紹介でも簡単に触れます。glm::to_string()を使えるようになります。 #include auto main() -> int { glm::mat4 m; std::cout << glm::to_string( m ) << "\n"; m *= 3.14f; std::cout << glm::to_string( m ) << "\n"; }
 mat4x4((1.000000, 0.000000, 0.000000, 0.000000), (0.000000, 1.000000, 0.000000, 0.000000), (0.000000, 0.000000, 1.000000, 0.000000), (0.000000, 0.000000, 0.000000, 1.000000)) mat4x4((3.140000, 0.000000, 0.000000, 0.000000), (0.000000, 3.140000, 0.000000, 0.000000), (0.000000, 0.000000, 3.140000, 0.000000), (0.000000, 0.000000, 0.000000, 3.140000))
 #include #include #include #include auto main() -> int { glm::mat4 m; m[0][1] = 1.73f; for ( auto a = 0; a < 4; ++a ) for ( auto b = 0; b < 4; ++b ) std::cout << m[a][b] << " "; std::cout << "\n" << glm::to_string( m ) << "\n" << *( reinterpret_cast< float* >( &m ) + 1 ) ; }
 1 1.73 0 0 0 1 0 0 0 0 1 0 0 0 0 1 mat4x4((1.000000, 1.730000, 0.000000, 0.000000), (0.000000, 1.000000, 0.000000, 0.000000), (0.000000, 0.000000, 1.000000, 0.000000), (0.000000, 0.000000, 0.000000, 1.000000)) 1.73
 #include #include #include auto main() -> int { std::cout << std::boolalpha << "pod : " << std::is_pod::value << "\n" << "standard layout: " << std::is_standard_layout::value << "\n" << "trivial : " << std::is_trivial::value ; }
 pod : false standard layout: true trivial : false
 struct vertex { glm::vec3 position; virtual auto f() -> void { }; }; struct vertex_ex1: vertex { glm::vec3 normal; }; struct vertex_ex2: vertex_ex1 { glm::vec2 texcoord0; }; std::cout << std::boolalpha << "vertex : " << std::is_standard_layout::value << " " << sizeof(vertex) << "\n" << "vertex_ex1: " << std::is_standard_layout::value << " " << sizeof(vertex_ex1) << "\n" << "vertex_ex2: " << std::is_standard_layout::value << " " << sizeof(vertex_ex2) << "\n" ;
 #include #include auto main() -> int { auto a = glm::vec2( 3, 4 ); std::cout << "a: " << a.x << " " << a.y << "\n" << "length(a): " << glm::length( a ) ; }
 vertex : false 24 vertex_ex1: false 32 vertex_ex2: false 40
 std::cout << glm::to_string( glm::abs( glm::vec3( 1, -1, -3 ) );
 vec3(1.000000, 1.000000, 3.000000)
 std::cout << glm::to_string( glm::ceil( glm::vec2( M_PI, -M_PI ) ) );
 vec2(4.000000, -3.000000)
 std::cout << glm::clamp( M_PI * 2, 0.0, M_PI / 2 );
 1.5708
 std::cout << std::hex << glm::floatBitsToUint( 1 );
 3f800000
 std::cout << glm::to_string( glm::floor( glm::vec2( M_PI, -M_PI ) ) );
 vim CMakeLists.txt
 vec2(3.000000, -4.000000)
 float f( const float a, const float b, const float c ) { return a * b + c; }
 0x00000000004008b0 <+0>: push %rbp 0x00000000004008b1 <+1>: mov %rsp,%rbp 0x00000000004008b4 <+4>: movss %xmm0,-0x4(%rbp) 0x00000000004008b9 <+9>: movss %xmm1,-0x8(%rbp) 0x00000000004008be <+14>: movss %xmm2,-0xc(%rbp) 0x00000000004008c3 <+19>: movss -0x4(%rbp),%xmm0 0x00000000004008c8 <+24>: mulss -0x8(%rbp),%xmm0 0x00000000004008cd <+29>: addss -0xc(%rbp),%xmm0 0x00000000004008d2 <+34>: pop %rbp 0x00000000004008d3 <+35>: retq
 0x00000000004008c0 <+0>: vmulss %xmm1,%xmm0,%xmm0 0x00000000004008c4 <+4>: vaddss %xmm2,%xmm0,%xmm0 0x00000000004008c8 <+8>: retq
 void f( const float* a, const float* b, const float* c, float* r ) { for( auto n = 0; n < 256; ++n ) r[n] = a[n] * b[n] + c[n]; }
 0x0000000000400800 <+112>: vmovups (%rdi,%rax,4),%ymm0 0x0000000000400805 <+117>: vmovups 0x20(%rdi,%rax,4),%ymm1 0x000000000040080b <+123>: vmovups 0x40(%rdi,%rax,4),%ymm2 0x0000000000400811 <+129>: vmovups 0x60(%rdi,%rax,4),%ymm3 0x0000000000400817 <+135>: vmulps (%rsi,%rax,4),%ymm0,%ymm0 0x000000000040081c <+140>: vmulps 0x20(%rsi,%rax,4),%ymm1,%ymm1 0x0000000000400822 <+146>: vmulps 0x40(%rsi,%rax,4),%ymm2,%ymm2 0x0000000000400828 <+152>: vmulps 0x60(%rsi,%rax,4),%ymm3,%ymm3 0x000000000040082e <+158>: vaddps (%rdx,%rax,4),%ymm0,%ymm0 0x0000000000400833 <+163>: vaddps 0x20(%rdx,%rax,4),%ymm1,%ymm1 0x0000000000400839 <+169>: vaddps 0x40(%rdx,%rax,4),%ymm2,%ymm2 0x000000000040083f <+175>: vaddps 0x60(%rdx,%rax,4),%ymm3,%ymm3 0x0000000000400845 <+181>: vmovups %ymm0,(%rcx,%rax,4) 0x000000000040084a <+186>: vmovups %ymm1,0x20(%rcx,%rax,4) 0x0000000000400850 <+192>: vmovups %ymm2,0x40(%rcx,%rax,4) 0x0000000000400856 <+198>: vmovups %ymm3,0x60(%rcx,%rax,4)
 std::cout << glm::fract( M_PI );
 0.141593
 int e; auto x = std::frexp( M_PI, &e); std::cout << M_PI << " = " << x << " x std::exp2( " << e << ")" << "\n" << " = " << ( x * std::exp2( e ) ) ;
 3.14159 = 0.785398 x std::exp2( 2) = 3.14159
 cmake_minimum_required(VERSION 2.8.12) project(hello_glm) if("\${CMAKE_SOURCE_DIR}" STREQUAL "\${CMAKE_BINARY_DIR}") message(SEND_ERROR "In-source builds are not allowed.") endif() set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) set(CMAKE_DISABLE_SOURCE_CHANGES ON) set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_COLOR_MAKEFILE ON) if (WIN32) set(CMAKE_SHARED_LIBRARY_PREFIX "") endif() if(CMAKE_CXX_COMPILER MATCHES "/em\\+\\+(-[a-zA-Z0-9.])?\$") set(CMAKE_CXX_COMPILER_ID "Emscripten") endif() if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) if(COMPILER_SUPPORTS_CXX11) set(CMAKE_CXX_FLAGS "\${CMAKE_CXX_FLAGS} -std=c++11") elseif(COMPILER_SUPPORTS_CXX0X) set(CMAKE_CXX_FLAGS "\${CMAKE_CXX_FLAGS} -std=c++0x") else() message(STATUS "The compiler \${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") endif() set(CMAKE_CXX_FLAGS "\${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic-errors") else() set(CMAKE_CXX_FLAGS "\${CMAKE_CXX_FLAGS} /Wall /Za") endif() include_directories(\${CMAKE_SOURCE_DIR}/submodule/glm) file(GLOB CXX_SOURCE_FILES *.cxx) if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Emscripten") set(TARGET \${PROJECT_NAME}) else() set(TARGET \${PROJECT_NAME}.html) endif() add_executable(\${TARGET} \${CXX_SOURCE_FILES})
 std::cout << std::hex << glm::floatBitsToUint( M_PI ) << "\n" << glm::uintBitsToFloat( 0x40490fdbu ) ;
 40490fdb 3.14159
 std::cout << std::boolalpha << glm::isinf( M_PI / 0 );
 true
 std::cout << std::boolalpha << glm::isinf( 0. / 0 );
 true
 std::cout << std::ldexp( 0.785398f, 2 );
 3.14159
 glm::vec3 a( 1, 7, -M_PI ); glm::vec3 b( 2, 3, std::cos(M_PI) ); std::cout << glm::to_string( glm::max( a, b ) );
 vec3(2.000000, 7.000000, -1.000000)
 mkdir build cd build cmake .. -G Ninja -DCMAKE_BIULD_TYPE=Debug
 glm::vec3 a( 1, 7, -M_PI ); glm::vec3 b( 2, 3, std::cos(M_PI) ); std::cout << glm::to_string( glm::min( a, b ) );
 vec3(1.000000, 3.000000, -3.141593)
 std::cout << glm::to_string( glm::mix( a, b, 4. / 5 ) );
 vec3(1.800000, 3.800000, -1.428319)
 std::cout // 480 [degrees] => 120 [degrees] << glm::mod( M_PI * 8 / 3 , M_PI * 2 ) << "\n" // -270 [degrees] => 90 [degrees] << glm::mod( -M_PI * 3 / 2 , M_PI * 2 ) ;
 2.0944 1.5708
 std::cout << glm::mod ( -45.f, 360.f ) << "\n" << glm::fmod ( -45.f, 360.f ) << "\n" << glm::remainder( -45.f, 360.f ) << "\n" << ( -45 % 360 ) << ;
 315 -45 -45 -45
 glm::vec2 x( M_PI, -M_PI ); glm::vec2 i; std::cout << glm::to_string( glm::modf( x, i　) ) << "\n"; std::cout << glm::to_string( i );
 vec2(0.141593, -0.141593) vec2(3.000000, -3.000000)
 ninja
 glm::vec2 x( M_PI, -M_PI ); std::cout << glm::to_string( glm::round( x ) ) << "\n";
 vec2(3.000000, -3.000000)
 glm::vec4 x( -1.5, -0.5, 0.5, 1.5 ); std::cout << glm::to_string( glm::roundEven( x ) ) << "\n";
 vec4(-2.000000, 0.000000, 0.000000, 2.000000)
 glm::vec4 x( -1.5, -0.5, 0.5, 1.5 ); std::cout << glm::to_string( glm::sign( x ) ) << "\n";
 vec4(-1.000000, -1.000000, 1.000000, 1.000000)
 glm::vec4 e1( 0, 0, 0, 0 ); glm::vec4 e2( 100, 100, 100, 100 ); glm::vec4 x( -20, 20, 40, 120 ); std::cout << glm::to_string( glm::smoothstep( e1, e2, x ) ) << "\n";
 vec4(0.000000, 0.104000, 0.352000, 1.000000)
 glm::vec4 e( 20, 20, 20, 20 ); glm::vec4 x( 0, 10, 20, 30 ); std::cout << glm::to_string( glm::step( e, x ) ) << "\n";
 vec4(0.000000, 0.000000, 1.000000, 1.000000)
 ./hello_glm
 glm::vec4 x( -1.5, -0.5, 0.5, 1.5 ); std::cout << glm::to_string( glm::trunc( x ) ) << "\n";
 vec4(-1.000000, -0.000000, 0.000000, 1.000000)
 #include #define GLM_SWIZZLE #include #include auto main() -> int { glm::vec4 a( 1, 2, 3, 4 ); auto b = a.zwyx(); auto c = a.rgb(); std::cout << glm::to_string( a ) << "\n" << glm::to_string( b ) << "\n" << glm::to_string( c ) << "\n" ; }
 precision mediump int; precision highp float;
 #define GLM_PRECISION_MEDIUMP_INT; #define GLM_PRECISION_HIGHP_FLOAT; #include
 #define GLM_MESSAGES #include
 #define GLM_FORCE_CXX14 #include
 // vec4 mat4 を SIMD 向けにします。 // 内部的に __mm128 なんかを使う事になります。 #define GLM_GTX_simd_vec4 #define GLM_GTX_simd_mat4 // SIMD命令セットを強制します。 #define GLM_FORCE_SSE2 #define GLM_FORCE_SSE3 #define GLM_FORCE_SSE4 #define GLM_FORCE_AVX #define GLM_FORCE_AVX2 // SIMD 命令を使いたく無い場合に誤って // GLM_GTX_simd_vec4 など明示されていた場合にエラーを出力するようにします。 #define GLM_FORCE_PURE
 #define GLM_FORCE_INLNIE #include
 #include
 a: 3 4 length(a): 5
 std::cout << glm::pi() << "\n" << glm::e() << "\n" << glm::three_over_two_pi() << "\n" ;
 3.14159 2.71828 4.71239
 #include
 glm::vec3 p0; std::cout << glm::to_string( p0 ) << "\n"; auto translation = glm::translate( glm::mat4(), glm::vec3( 0, 0, 1 ) ); std::cout << glm::to_string( ( translation * glm::vec4( p0, 1 ) ).xyz() ) << "\n"; auto rotation = glm::rotate( glm::mat4(), float(M_PI) / 4, glm::vec3( 1, 0, 0 ) ); std::cout << glm::to_string( ( rotation * translation * glm::vec4( p0, 1 ) ).xyz() ) << "\n";
 vec3(0.000000, 0.000000, 0.000000) vec3(0.000000, 0.000000, 1.000000) vec3(0.000000, -0.707107, 0.707107)
 #include #include #include auto main() -> int { std::ofstream o("simplex.pgm"); o << "P2\n256 256\n255\n"; for ( auto y = 0; y < 256; ++y ) { for ( auto x = 0; x < 256; ++x ) o << glm::roundEven( ( glm::simplex( glm::vec2( x / 64., y / 64. ) ) + 1.0f) * 255 / 2 ) << " "; o << "\n"; } }
 #include #include #include auto main() -> int { std::ofstream o("perlin.pgm"); o << "P2\n256 256\n255\n"; for ( auto y = 0; y < 256; ++y ) { for ( auto x = 0; x < 256; ++x ) o << glm::roundEven( ( glm::perlin( glm::vec2( x / 8., y / 8. ) ) + 1.0f) * 255 / 2 ) << " "; o << "\n"; } }
 glm::vec3 p0( 0, 0, 1 ); glm::quat q1( glm::vec3( M_PI / 2, 0, 0 ) ); glm::quat q2( glm::vec3( 0, M_PI / 2, 0 ) ); auto p1 = q1 * p0; auto p2 = q2 * p0; auto p3 = glm::slerp( q1, q2, .5f ) * p0; std::cout << glm::to_string( p1 ) << "\n" << glm::to_string( p2 ) << "\n" << glm::to_string( p3 ) ;
 vec3(0.000000, -1.000000, 0.000000) vec3(1.000000, 0.000000, 0.000000) vec3(0.666667, -0.666667, 0.333333)
 auto rgb = glm::vec3( 0.5, 0.5, 0.25 ); auto hsv = glm::hsvColor( rgb ); std::cout << glm::to_string( hsv );
 // A.1. glm ライブラリーの一部機能は CPP を定義して制御できるようになっています。 #define GLM_SWIZZLE // 1. glm ライブラリーの基本機能が含まれます。 #include // 2. glm ライブラリーの拡張機能のうち既に仕様が安定した機能が glm/gtc に含まれます。 #include // 3. glm ライブラリーの拡張機能のうち試験的に実装されている機能が glm/gtx に含まれます。 #include // 4. glm ライブラリーの拡張機能をひとまとめに取り込みたい場合には glm/ext.hpp を使います。 #include auto main() -> int { // glm ライブラリーの機能は基本的には glm 名前空間に定義されます。 glm::vec2 a, b; } // glm は C++ ヘッダーオンリーライブラリーとして提供されているため、 // 翻訳時にヘッダーファイルが取り込まれていれば // バイナリーライブラリーのリンクなどは必要ありません。
 vec3(60.000000, 0.500000, 0.500000)
 std::cout << glm::to_string( glm::vec4() ) << "\n" << glm::to_string( glm::mat4() ) ;
 vec4(0.000000, 0.000000, 0.000000, 0.000000) mat4x4((1.000000, 0.000000, 0.000000, 0.000000), (0.000000, 1.000000, 0.000000, 0.000000), (0.000000, 0.000000, 1.000000, 0.000000), (0.000000, 0.000000, 0.000000, 1.000000))
 // ヘッダーファイルでは前方宣言のみ扱う #include
 // ソースファイルでは定義本体を扱う #include