Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@usagi
Last active August 29, 2015 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save usagi/6e7e22b0f52a8d597657 to your computer and use it in GitHub Desktop.
Save usagi/6e7e22b0f52a8d597657 to your computer and use it in GitHub Desktop.
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 <iostream>
#include <glm/glm.hpp>
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 <iostream>
#include <glm/glm.hpp>
// あとで gtx 拡張の紹介でも簡単に触れます。glm::to_string()を使えるようになります。
#include <glm/gtx/string_cast.hpp>
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 <iostream>
#include <glm/glm.hpp>
#include <glm/gtx/string_cast.hpp>
#include <type_traits>
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 <iostream>
#include <type_traits>
#include <glm/glm.hpp>
auto main()
-> int
{
std::cout
<< std::boolalpha
<< "pod : " << std::is_pod<glm::vec4>::value << "\n"
<< "standard layout: " << std::is_standard_layout<glm::vec4>::value << "\n"
<< "trivial : " << std::is_trivial<glm::vec4>::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<vertex>::value << " " << sizeof(vertex) << "\n"
<< "vertex_ex1: " << std::is_standard_layout<vertex_ex1>::value << " " << sizeof(vertex_ex1) << "\n"
<< "vertex_ex2: " << std::is_standard_layout<vertex_ex2>::value << " " << sizeof(vertex_ex2) << "\n"
;
#include <iostream>
#include <glm/glm.hpp>
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 );
std::cout << std::hex << glm::floatBitsToUint( 1 );
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 );
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 );
std::cout << std::boolalpha << glm::isinf( 0. / 0 );
std::cout << std::ldexp( 0.785398f, 2 );
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)
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 <iostream>
#define GLM_SWIZZLE
#include <glm/glm.hpp>
#include <glm/gtx/string_cast.hpp>
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 <glm/glm.hpp>
#define GLM_MESSAGES
#include <glm/glm.hpp>
#define GLM_FORCE_CXX14
#include <glm/glm.hpp>
// 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 <glm/glm.hpp>
#include <glm/gtc/constatns.hpp>
a: 3 4
length(a): 5
std::cout
<< glm::pi<double>() << "\n"
<< glm::e<double>() << "\n"
<< glm::three_over_two_pi<double>() << "\n"
;
3.14159
2.71828
4.71239
#include <glm/gtc/matrix_transform.hpp>
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 <fstream>
#include <glm/glm.hpp>
#include <glm/gtc/noise.hpp>
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 <fstream>
#include <glm/glm.hpp>
#include <glm/gtc/noise.hpp>
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 <glm/glm.hpp>
// 2. glm ライブラリーの拡張機能のうち既に仕様が安定した機能が glm/gtc に含まれます。
#include <glm/glc/constants.hpp>
// 3. glm ライブラリーの拡張機能のうち試験的に実装されている機能が glm/gtx に含まれます。
#include <glm/gtx/color_space.hpp>
// 4. glm ライブラリーの拡張機能をひとまとめに取り込みたい場合には glm/ext.hpp を使います。
#include <glm/ext.hpp>
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 <glm/fwd.hpp>
// ソースファイルでは定義本体を扱う
#include <glm/glm.hpp>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment